对指令和父范围进行AngularJS ng-repeat

时间:2014-10-27 23:34:56

标签: javascript angularjs

我有一个重复的指令,它继承了它的父控制器的范围。

    <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进行双向绑定?

3 个答案:

答案 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不再影响父范围。

希望这有帮助! :)