angularjs范围(症结):父子范围有模型(有和没有'点')

时间:2015-11-20 06:40:54

标签: angularjs angularjs-scope

示例没有'点' 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>

示例 WITH &#39;点&#39; 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代码

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)如果没有&#39; dot&#39; (就像范围内的原始变量) 1.编辑&#39; ctrl值&#39;它将使用此值反映在所有其他值(child1和child2)中 2.编辑&#39; Child1 ctrl值&#39;它只会反映在child2中 3.编辑&#39; Child2 ctrl值&#39;它只会反映在child2中 4.现在编辑&#39; ctrl值&#39;它将仅反映在父ctrl中

B)如果有点&#39; (像范围内的对象) 按照A)1到A)4步,您将看到任何ctrl中的任何更改都将反映在所有值中

为什么会这样?

2 个答案:

答案 0 :(得分:0)

Angular为每个控制器创建子范围。在模型中有一个点不会改变任何东西。

当你在ng-model="name"的字段中输入'foo'时,这是当前控制器范围的角度:

scope.name = 'foo';

如果父作用域中已存在name字段,则不受影响。所以你最终得到了

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

现在当你在ng-model="user.name"的字段中输入'foo'时,这里的角度基本上与当前控制器的范围有关:

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

因此,如果父作用域已经有一个用户,并且name属性的值为'some previous value',那么最终会得到

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

为什么呢?因为范围原型继承自父范围,所以在评估scope.user时,JavaScript在范围对象上找不到user属性,因此它在原型(父范围)上查找它,找到它。因此父和子共享一个用户对象,scope.user.name = 'foo'更改此共享对象的name属性。

答案 1 :(得分:0)

正如我们所知,angularjs中的子范围创建基于原型继承。 因此,在显示值时,它会在当前范围(子范围)中搜索名称&#39;,在这种情况下,这两个子范围都没有任何&#39;名称&#39;变量,因此它将从父作用域中读取并显示在每个子作用域中。

基本规则:因此,如果未找到,则读取值将搜索父母。

但是写一个值总是直接写入对象,即使它也被定义得更高。

如果child1或child2中的一个尝试写入父级的范围,则它仅适用于对象var(非原始)类型。原因是对象(非原始)类型通过引用传递。 换句话说,当它尝试编写普通变量(原始)时,它将写入当前范围(在案例A中)子范围),因此它不会反映在其他范围中。