用于访问父范围的控制器层次结构异常:AngularJS

时间:2015-01-04 20:23:30

标签: javascript angularjs angularjs-scope angularjs-controller

我是angularjs的新手并且遇到了令人困惑的事情,我认为这可能是访问父范围的控制器层次结构中的一个异常现象。下面是两个代码片段,我认为两者都必须按照访问父范围的原则工作,但是......

1)这个正在运作:

<body data-ng-app>
<div data-ng-controller="ctrl1">
    Greeted : {{first.greeted}} 
    <div data-ng-controller="ctrl2">
        <a href="#" data-ng-click="sayClick()">Click To Greet</a>
    </div>
</div>

<script>
function ctrl1($scope){
    $scope.first = {greeted: "No"};
}
function ctrl2($scope){
    $scope.sayClick= function(){
        $scope.first.greeted = "Yes";
    }
}
</script>
</body>

2)而这个不是:

<body data-ng-app>
<div data-ng-controller="ctrl1">
    Greeted : {{first}} 
    <div data-ng-controller="ctrl2">
        <a href="#" data-ng-click="sayClick()">Click To Greet</a>
    </div>
</div>

<script>
function ctrl1($scope){
    $scope.first = "No";
}
function ctrl2($scope){
    $scope.sayClick= function(){
        $scope.first = "Yes";
    }
}
</script>
</body>

有人可以告诉我两者之间的区别以及为什么第二个不起作用?

2 个答案:

答案 0 :(得分:1)

在角度范围内,继承是使用标准Javascript原型继承实现的。两个例子之间的区别在于,在第二个例子中,你处理原始值,这些原始值不能以你的思维方式继承。当你这样做

$scope.first = "Yes";

在第二个控制器中,它只是创建了新的范围属性&#34; shadow&#34; 父范围属性。但是在第一个示例中,first.greeted是对父作用域对象first的对象引用,并且由于它不是原始对象,因此它保留了对象引用。

为了说明纯Javascript对象的问题(在Angular代码中也是如此),请考虑这个小例子。

&#13;
&#13;
var obj1 = {
    profile: {   // object
        id: 1
    },
    name: 'Obj1' // primitive
};

// create obj2 with obj1 set as its prototype
var obj2 = Object.create(obj1);

// Change promitive and object referenced property
obj2.name = 'Obj2';
obj2.profile.id = 2;


document.body.innerHTML = obj1.name + ', ' + obj2.name;
document.body.innerHTML += '<br>' + obj1.profile.id + ', ' + obj2.profile.id;
&#13;
&#13;
&#13;

为避免混淆,经常建议使用对象引用,即"dot-rule"

答案 1 :(得分:1)

在第一种情况下,您正在处理对象,在第二种情况下,在范围内使用直接原始值。

a)每个控制器创建自己的范围; b)angular上升到范围层次结构,直到它找到它所寻找的OBJECT,但是 c)如果不是一个对象,而是一个值,它会在当前控制器的作用域中创建PRIMITIVE值,覆盖并重置先前从父作用域继承的值。

为避免这种混淆,请始终使用对象。而不是$ scope.A和$ scope.B,创建像$ scope.data = {}之类的东西,然后分配$ scope.data.A和$ scope.data.B

然后在您的视图中,您引用data.A和data.B嵌套控制器将上升到层次结构,直到找到数据对象而不是创建新数据对象。