AngularJS中的$watch
函数接受可选的第三个参数。
如果是false
(默认值),只要观察的参考值发生变化,手表就会触发。如果是true
,只要观察对象根据angular.equals
发生变化,手表就会触发(这基本上意味着观察对象中存储的值必须更改)。
现在,如果观看的参考或其内容发生了变化,我正在寻找让手表触发其功能的方法。有没有办法实现这个目标?
提供我所看到的困难的一个例子:
我们假设我有一系列内容可编辑的对象:
var allItems = [{id: 1, a: []}, {id: 2, a: [2, 3, 5]}, {id: 3, a: [4, 6]}, {id: 4, a: []}];
我的编辑器范围内的字段会收到对a
属性值的引用。例如,如果选择了第1项,则会发生以下情况:
$scope.currentItem = [];
此外,我在该字段上注册了一个检查值相等的手表:
$scope.$watch('currentItem', watchFunc, true);
现在,我必须区分两种情况:
[]
扩展为[4, 6]
。从watchFunc
开始,这些变化乍一看似乎都是一样的。为了区分是否选择了新项目,我需要以某种方式保留以前的ID,如果它与当前ID不同,我需要忽略更改(因为没有在数据中编辑任何内容,只是切换了所选项目) 。然后,我需要使用watchFunc
将当前项ID设置为下次调用的先前ID。
但是,在以下情况下,这是有问题的:
此处的问题是,第二个操作不会根据angular.equals
触发监视。因此,当选择更改时,不会更新所选项目ID。相反,将在步骤3中注意到不同的项ID,这将导致实际的编辑操作被忽略。
显然,这个例子非常简单;实际上,我的对象图由嵌套的对象数组组成,每个对象具有各种相关属性。
答案 0 :(得分:0)
工作jsfiddle:http://jsfiddle.net/qybc07zs/
希望这是你正在寻找的东西。
测试场景:
1. Select 1
2. Input 4 => Add
3. Input 6 => Add
4. Select 3
5. $watch occurs
<强> AngularJS:强>
var myApp = angular.module('myApp',[]);
myApp.controller('myCtrl', myCtrl);
function myCtrl($scope) {
$scope.allItems = [{id: 1, a: []}, {id: 2, a: [2, 3, 5]}, {id: 3, a: [4, 6]}, {id: 4, a: []}];
$scope.currentItemObject = {};
$scope.currentItem = [];
$scope.updateCurrentItem = function(item){
$scope.currentItem = angular.copy(item.a);
};
$scope.addItem = function(){
if($scope.newItem !== undefined){
$scope.currentItem.push($scope.newItem);
$scope.newItem = undefined;
}
};
$scope.$watch(function(){
return {id: $scope.currentItemObject.id, a: $scope.currentItem};
},function(newValue, oldValue){
if(newValue !== oldValue){
console.log('$watch', $scope.currentItem);
$scope.lastUpdate = new Date().toLocaleTimeString();
}
},true);
}
<强> HTML:强>
<div ng-controller="myCtrl">
<label>Items:
<select ng-options="item as item.id for item in allItems"
ng-model="currentItemObject"
ng-change="updateCurrentItem(currentItemObject)">
<option style="display:none" value="">-- select item --</option>
</select>
</label>
<div>
<label>New item
<input type="number" ng-model="newItem">
</label>
<button type="button" ng-click="addItem()">
Add
</button>
</div>
<div>
Current item: {{currentItem}}
</div>
<br/>
<pre>
Last update: {{lastUpdate}}
</pre>
</div>