我想观察字典中的更改,但出于某种原因,不会调用监视回调。
这是我使用的控制器:
function MyController($scope) {
$scope.form = {
name: 'my name',
surname: 'surname'
}
$scope.$watch('form', function(newVal, oldVal){
console.log('changed');
});
}
这是fiddle。
我希望每次更改名称或姓氏时都会触发$ watch回调,但不会发生。
这样做的正确方法是什么?
答案 0 :(得分:555)
使用$watch
作为第三个参数调用true
:
$scope.$watch('form', function(newVal, oldVal){
console.log('changed');
}, true);
默认情况下,当比较JavaScript中的两个复杂对象时,将检查它们是否为“引用”相等,它会询问两个对象是否引用相同的东西,而不是“值”相等,它会检查所有的值是否为这些对象的属性是相同的。
根据Angular documentation,第三个参数适用于objectEquality
:
当
objectEquality == true
时,watchExpression的不等式是根据angular.equals
函数确定的。要保存对象的值以供以后比较,请使用angular.copy
函数。因此,这意味着观看复杂的物体会对记忆和性能产生不利影响。
答案 1 :(得分:13)
form
对象未更改,只有name
属性为
更新fiddle
function MyController($scope) {
$scope.form = {
name: 'my name',
}
$scope.changeCount = 0;
$scope.$watch('form.name', function(newVal, oldVal){
console.log('changed');
$scope.changeCount++;
});
}
答案 2 :(得分:12)
很少效果提示如果某人拥有带密钥的数据存储类服务 - >价值对:
如果您有一项名为 dataStore 的服务,则只要您的大数据对象发生更改,您就可以更新时间戳。 这样,您只需要观察变化的时间戳,而不是深入观察整个对象。
app.factory('dataStore', function () {
var store = { data: [], change: [] };
// when storing the data, updating the timestamp
store.setData = function(key, data){
store.data[key] = data;
store.setChange(key);
}
// get the change to watch
store.getChange = function(key){
return store.change[key];
}
// set the change
store.setChange = function(key){
store.change[key] = new Date().getTime();
}
});
在指令中,您只是在观看要更改的时间戳
app.directive("myDir", function ($scope, dataStore) {
$scope.dataStore = dataStore;
$scope.$watch('dataStore.getChange("myKey")', function(newVal, oldVal){
if(newVal !== oldVal && newVal){
// Data changed
}
});
});
答案 3 :(得分:5)
您的代码无法正常工作的原因是默认情况下$watch
会引用检查。简而言之,它确保传递给它的对象是新对象。但在您的情况下,您只是修改表单对象的某些属性而不是创建新的属性。为了使其工作,您可以将true
作为第三个参数传递。
$scope.$watch('form', function(newVal, oldVal){
console.log('invoked');
}, true);
它可以工作,但你可以使用$ watchCollection,这比$ watch更有效,因为$watchCollection
将监视表单对象的浅层属性。 E.g。
$scope.$watchCollection('form', function (newVal, oldVal) {
console.log(newVal, oldVal);
});
答案 4 :(得分:4)
当您正在寻找表单对象更改时,最佳观看方法是使用
$watchCollection
。有关不同的性能特征,请查看官方documentation。
答案 5 :(得分:1)
试试这个:
function MyController($scope) {
$scope.form = {
name: 'my name',
surname: 'surname'
}
function track(newValue, oldValue, scope) {
console.log('changed');
};
$scope.$watch('form.name', track);
}
答案 6 :(得分:0)
对于任何想要观察对象数组中对象的更改的人来说,这似乎对我有用(因为此页面上的其他解决方案没有):
function MyController($scope) {
$scope.array = [
data1: {
name: 'name',
surname: 'surname'
},
data2: {
name: 'name',
surname: 'surname'
},
]
$scope.$watch(function() {
return $scope.data,
function(newVal, oldVal){
console.log(newVal, oldVal);
}, true);
答案 7 :(得分:-4)
你必须改变$ watch ....
function MyController($scope) {
$scope.form = {
name: 'my name',
}
$scope.$watch('form.name', function(newVal, oldVal){
console.log('changed');
});
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app>
<div ng-controller="MyController">
<label>Name:</label> <input type="text" ng-model="form.name"/>
<pre>
{{ form }}
</pre>
</div>
</div>