angularjs scope(the crux): parent child scope having model(with and without 'dot')

时光总嘲笑我的痴心妄想 提交于 2019-12-20 03:44:14

问题


Example WITHOUT 'dot' http://jsfiddle.net/CmXaP/168/

<div ng-app="myapp">
    <div ng-controller="parent">
        Parent ctrl value: <input type="text" data-ng-model="name" />

        <div ng-controller="child1">
            Child1 ctrl value: <input type="text" data-ng-model="name" />
                        <div ng-controller="child2">
                            Child2 ctrl value: <input type="text" data-ng-model="name" />
                        </div>

        </div>

 Parent ctrl value(after child1 ctrl block): {{name}}
    </div>
</div>

Example WITH 'dot' http://jsfiddle.net/CmXaP/167/

<div ng-app="myapp">
    <div ng-controller="parent">
        Parent ctrl value: <input type="text" data-ng-model="user.name" />

        <div ng-controller="child1">
            Child1 ctrl value: <input type="text" data-ng-model="user.name" />
                        <div ng-controller="child2">
                            Child2 ctrl value: <input type="text" data-ng-model="user.name" />
                        </div>

        </div>

 Parent ctrl value(after child1 ctrl block): {{user.name}}
    </div>
</div>

Javascript code

var ngapp = angular.module('myapp',[]);

ngapp.controller("parent", ['$scope', function($scope) {
  $scope.user = {
      name : 'anil'
  };
}]);
ngapp.controller("child1", ['$scope', function($scope) {}]);
ngapp.controller("child2", ['$scope', function($scope) {}]);

A) In case of without 'dot' (like primitive var in scope) 1. Edit 'Parent ctrl value' and it will reflect in all other values(child1 and child2) with this value 2. Edit 'Child1 ctrl value' and it will reflect in child2 only 3. Edit 'Child2 ctrl value' and it will reflect in child2 only 4. Now edit 'Parent ctrl value' and it will reflect in Parent ctrl only

B) In case of with 'dot' (like object in scope) Follow A)1 to A)4 steps and you will see any changes in any ctrl will reflect in all values

why this is so?


回答1:


Angular creates a child scope for each controller. Having a dot in the model doesn't change anything to that.

When you enter 'foo' in a field with ng-model="name", here's what angular does with the scope of the current controller:

scope.name = 'foo';

If there was already a name field in the parent scope, it's unaffected. So you end up with

parentScope ---> name --> 'some previous value'
scope ---------> name --> 'foo'

Now when you enter 'foo' in a field with ng-model="user.name", here's what angular basically does with the scope of the current controller:

if (!angular.isDefined(scope.user)) {
    scope.user = {};
}
scope.user.name = 'foo';

So, if the parent scope already had a user, with a name attribute having the value 'some previous value', you end up with

parentScope --> user ------> name ----> 'foo
                 ^
scope ----------/

Why? Because the scope prototypically inherits from the parent scope, so when evaluating scope.user, JavaScript doesn't find a user attribute on the scope object, so it looks for it on the prototype (the parent scope), and finds it. Both the parent and the child thus share a single user object, and scope.user.name = 'foo' changes the name attribute of this shared object.




回答2:


As we know child scope creation in angularjs is based on prototypal inheritance. Therefore, while while displaying the values it searches the current scope(child scope) for 'name', here in this case both child scopes does not have any 'name' variable, so it will be read from parent scope and will display in each child scope.

Basic rule: So reading a value will search the parents if it is not found.

But while writing a value always writes directly to the object, even if it is also defined higher up.

If one of child1 or child2 tries to write to parent's scope, it will work only on object var(non-primitive) types. The reason for this is that object(non-primitive) types are passed by reference. In other way when it tries to write normal variable(primitive) it will write into the current scope(in case A) child scope), hence it is not getting reflected in other scopes.



来源:https://stackoverflow.com/questions/33820473/angularjs-scopethe-crux-parent-child-scope-having-modelwith-and-without-dot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!