如果我直接在ng-repeat中使用输入字段,则在从列表更改中获取通知时会遇到一些问题。否则,我可以更改值并从$ watchCollection获得通知。

一个简化的例子:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.js">
    </script>
</head>
<body>
    <section ng-app="myApp" ng-controller = "TestController">
        <button ng-click = "pushToList()">Add number to list.</button>
        <button ng-click = "changeFirstElement()">Change first element.</button>
        <textarea ng-model = "log"></textarea>
        <ul>
            <li ng-repeat="item in list track by $index">
                <input ng-model="item"> Value: <span ng-bind="item"></span>
            </li>
        </ul>
    </section>
    <script>
        angular.module("myApp", [])
            .controller("TestController", function($scope){
                $scope.log = '';
                $scope.list = $scope.list = [1];

                $scope.pushToList = function() {
                    $scope.list.push(Math.random());
                }

                $scope.changeFirstElement = function() {
                    $scope.list[0] = Math.random();
                }

                $scope.$watchCollection(
                    'list',
                    function(currentValue, oldValue) {
                    $scope.log += [
                        'Current value:',
                        currentValue.toString(),
                        'Old value:',
                        oldValue ? oldValue.toString() : '',
                        '-----',
                        '',
                    ].join('\n')
        }
     )
        });
    </script>
</body>
</html>


当我通过调用$scope.list[0] = Math.random();进行更改时,$ watchCollection会“看到”,但是当我使用输入字段时,更改会被$ watchCollection忽略或“未看到”。为什么是这样?那我该怎么办呢?

而且我知道我可以使用更深的$ watch来代替,但是我对如何使用$ watchCollection实现这一点很感兴趣。另外,因为如果我正确理解它,性能会更好(请参见this question)。

编辑:

这是plunkr

当您单击“将数字添加到列表”时,$ watchCollection将看到更改,并将数组的当前内容写入到textarea中。当您通过单击“更改第一个元素”更改第一个数字时,$ watchCollection确实看到已进行了更改,然后将数组上的当前内容再次写入了textarea。当您使用ng-repeat放置输入字段来更改值时,该输入字段的数组项为ng-model。我希望如果我在输入字段中更改一个值,它会触发与单击“更改第一个元素”时相同的行为,但是:我希望$ watchCollection应该看到有更改,并且我注册的函数应该编写文本区域数组的内容。但这不会发生。

最佳答案

问题不在$ watchCollection中。 ng-repeat为每个子级创建作用域,因此,在输入中键入内容时,您只能在ng-repeat子级作用域中更改item属性,因为item是原始的。如果您有$ scope.list = [{value:1}],则可以更改父作用域中的值,也可以更改子作用域中的值,因为list [0]和项目共享同一对象上的引用。但是watchCollection仍然不会被解雇,因为它只检测浅表的更改。

关于javascript - AngularJS $ watchCollection与ng-repeat结合,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27802752/

10-10 06:38