我是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>
有人可以告诉我两者之间的区别以及为什么第二个不起作用?
答案 0 :(得分:1)
在角度范围内,继承是使用标准Javascript原型继承实现的。两个例子之间的区别在于,在第二个例子中,你处理原始值,这些原始值不能以你的思维方式继承。当你这样做
$scope.first = "Yes";
在第二个控制器中,它只是创建了新的范围属性&#34; shadow&#34; 父范围属性。但是在第一个示例中,first.greeted
是对父作用域对象first
的对象引用,并且由于它不是原始对象,因此它保留了对象引用。
为了说明纯Javascript对象的问题(在Angular代码中也是如此),请考虑这个小例子。
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;
为避免混淆,经常建议使用对象引用,即"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嵌套控制器将上升到层次结构,直到找到数据对象而不是创建新数据对象。