我有一个重复的指令,它继承了它的父控制器的范围。
<div ng-controller="myController">
{{ message }}
<person ng-repeat="person in persons"></person>
</div>
app.controller('myController', function ($scope) {
$scope.message = "A";
$scope.persons = { 1: {}, 2: {}, 3: {} }
});
但是当我更改指令内的范围时,父范围不会更新。
app.controller('PersonController', function ($scope) {
$scope.message = "B";
});
app.directive("person", function () {
return {
restrict: 'E',
transclude: true,
controller: 'PersonController',
template: '{{ message }}'
};
});
http://jsfiddle.net/hientc/L8xo9338/1/
只有当我对指令进行ng-repeat时才会发生这种情况。如果我删除ng-repeat,则在更新指令范围时更新父范围。
如何为ng-repeat进行双向绑定?
答案 0 :(得分:3)
将message
的实例更改为message.value
。
HTML:
<div ng-app="myApp">
<div ng-controller="myController">
{{ message.value }}
<person ng-repeat="person in persons"></person>
</div>
</div>
JS:
// Inside myController
$scope.message = {
value: "A"
};
// Inside PersonController
app.controller('PersonController', function ($scope) {
$scope.message.value = "B";
});
http://jsfiddle.net/L8xo9338/2/
这与范围使用javascript的prototype
继承的方式有关。有关说明,请参阅What are the nuances of scope prototypal / prototypical inheritance in AngularJS?。
基本上,当您创建对象时,范围引用相同的对象以便更新。
这可以通过$scope.$parent.message = "B";
替代完成。但是,对我来说它不太干净。
您甚至可以将其绑定到模型,例如<input ng-model="message.value">
它将在父级和子级中更新。
答案 1 :(得分:0)
我认为您的问题与JavaScript的原型继承有关,当您阅读或撰写成员时,其行为会有所不同:
您的指令创建一个新范围并尝试在其上设置message
成员。由于该成员不存在,因此它是在该作用域上创建的(而不是如您所想,可以在已具有此成员的父作用域上设置)。这意味着message
成员是在“错误”范围内创建的(对于您要执行的操作)。
写行为与读取行为不同。如果您尝试从父作用域上的子作用域访问属性,则会冒泡,直到找到该属性,否则它将为undefined
。
这可以通过方法设置值来解决。此方法应放在具有需要设置的成员的范围上。在你的情况下,这样的事情应该有效:
在myController
:
$scope.SetMessage = function(m)
{
$scope.message = m;
}
PersonController
应更改如下:
app.controller('PersonController', function ($scope)
{
$scope.SetMessage("B");
});
您也可以通过$scope.$parent
访问父作用域,这可能暂时有用,但只要添加/删除作用域就会中断(例如,将其嵌套在另一个指令中)。使用方法更灵活。顺便说一句:这就是为什么它不能与ng-repeat
一起使用,因为这会为每个项目创建一个新范围。
答案 2 :(得分:0)
首先,您的person
指令 NOT 创建任何新范围,它会重用与其父级相同的范围。这就是为什么当你没有使用ng-repeat
其次,ng-repeat
会创建新范围。根据{{3}}
每个模板实例都有自己的范围,其中给定的循环变量设置为当前集合项
因此,当您使用ng-repeat
时,即使您的指令仍然没有创建新范围,它也会共享由ng-repeat
创建的新范围。这就是为什么在指令中设置message
不再影响父范围。
希望这有帮助! :)