如果我直接在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/