When working with AngularJS, $scope
will have a pivotal role in your work and when starting out, you might run into road bumps unless you have a rough idea of how to work with it. I’ll aim to explain a couple issues about $scope
and ngInclude
that I’ve run into.
Below you’ll learn how to avoid targeting $parent
or $child
scopes when using ng-include
, and how to debug your code when realizing that $watch
ers aren’t operating on the correct model or scope.
First, you need to understand this: Each controller has its own scope, and each scope has a unique ID. Listeners/watchers will apply only to the models in the scope where they were applied.
For instance, a watcher in controller AppCtrl.js
who listens to $scope.my_model
, will only listen to that model in that scope, not on my_model
in a scope with a different ID.
You can find the scope ID in $scope.$id
.
console.log($scope.$id);
When working with nested controllers, such as the example below..
index.html
<div ng-controller="AppCtrl">
<div ng-controller="LoginCtrl">
// Login code..
</div>
<div ng-controller="TableCtrl">
// Table codes...
</div>
</div>
.. the $scope.$id
of AppCtrl
, will be 001
, but for LoginCtrl
it may be 002
.
If by chance you need to apply a change to a model on the AppCtrl
‘s scope, from the LoginCtrl
, you can do so by targeting its parent scope $scope.$parent
, though if you find yourself targeting different scope than your controllers’ natural scope, it’s probable you should move your functionality to its appropriate controller instead.
Here’s something that threw me off, ngInclude
creates a new scope!
You’ll need to keep that in mind when using ngInclude
to split your templates into partials. Instead of applying a controller to an element in a layout-template, apply the controller to an element in the partial. That way you’ll not need to target its parent’s scopes, coupling controllers together by scope. Here’s an example:
layout.html
<div ng-controller="LoginCtrl">
<div ng-include="login.html"></div>
</div>
login.html
<form-field ng-field-data=""></form-field>
<form-field ng-field-data=""></form-field>
In the case above, you would want to handle the login
model in the LoginCtrl
controller, but the scope of the login partial login.html
will be one step deeper. Instead, define the controller on the same level as the partial (see below).
layout.html
<div ng-include="login.html"></div>
login.html
<div ng-controller="LoginCtrl">
<form-field ng-field-data=""></form-field>
<form-field ng-field-data=""></form-field>
</div>
$scope
is an important part of AngularJS and the more understanding you have about it, the better and more testable code you will write. To get more in-depth information, here are a few links that explain this further. Thanks for checking in!