Reputation: 12729
I take two example in angular js but I am getting unexpected result .Example of nested controller :
First example
<div ng-controller="maincontroller">
<input ng-model="data.name">
<h1>{{data.name}}</h1>
<div ng-controller="nestedcontroller">
<input ng-model="data.name">
<h1>{{data.name}}</h1>
<div ng-controller="nestedANOTHERcontroller">
<input ng-model="data.name">
<h1>{{data.name}}</h1>
</div>
</div>
<div ng-controller="nestedOUTERRcontroller">
<input ng-model="data.name">
<h1>{{data.name}}</h1>
</div>
</div>
when I take "data.name" in all nested controller .Now when I change any input field it reflect in all input field and header field.why ?
Secondly when I take "name" instead of "data.name"
<div ng-controller="maincontroller">
<input ng-model="name">
<h1>{{name}}</h1>
<div ng-controller="nestedcontroller">
<input ng-model="name">
<h1>{{name}}</h1>
<div ng-controller="nestedANOTHERcontroller">
<input ng-model="name">
<h1>{{name}}</h1>
</div>
</div>
<div ng-controller="nestedOUTERRcontroller">
<input ng-model="name">
<h1>{{name}}</h1>
</div>
</div>
when I change on top input field it change in all input field and header field.but when i move to second input field it change to it's nested(children) input field and header but not change to upper controller and sibling controller why ? and when I move to inner most controller and change the text inside the input field it show header .Now if it parent controller try to change its text it it is not able to do .parents controller now change its only its text why ?
here is my code http://codepen.io/anon/pen/xGGJKR
Thanks
Upvotes: 0
Views: 134
Reputation: 49590
This has to do with how scope inheritance works. For a more comprehensive answer on nuances of scope inheritance, read this SO answer.
First, you have to recognize that ng-controller
directive creates a child scope that prototypically inherits from the parent, and so you have nested scopes here of the following hierarchy (the numbers are $id
s of each scope)
#2
/ \
#5 #3
\
#4
So, when you type something in the first <input>
it will create $scope.data = {name: "foo"}
in scope #2
and will be inherited (visible) by all the nested scopes. On the other hand, if you type in the second <input>
- then it will create $scope.data
(as above) in scope #3
, but neither #2
nor #5
will inherit it.
Second point has to do with setting the value when you use data.name
vs name
. Again, this has to do with nuances of prototypical inheritance.
When ng-model
sets the variable data.name
, it writes into the inherited data
object under name
property - as expected - wherever data
was defined. In other words, the data
object is read (and thus the inherited object is read) and the name
property is written into.
When, however, ng-model
sets the variable name
, then it will write directly into the property name
of the current scope, thus shadowing the inherited name
property from the parent.
The proper approach is:
ng-model
(or any two-way bound attributes).define the data
object based on where you want it to be - don't leave it up to the ng-model
to define. For example (if this is the intent), define it in the maincontroller
:
.controller("maincontroller", function($scope){
$scope.data = {};
});
The effect of that would be that all the inputs would be bound to the same property.
Upvotes: 1
Reputation: 19748
The short answer is prototypical inheritance of the scope properties (don't use the scope as your model instead create a reference to your model from some property of the scope). Typically use a service or a factory or some other provider definition to store the model and do most of the work and just use the controller to make the appropriate providers and data available to the view.
https://youtu.be/ZhfUv0spHCY?t=31m12s
What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
Upvotes: 0