$看一个对象

我想观察字典中的更改,但由于某种原因,不会调用callback函数。

这是我使用的一个控制器:

function MyController($scope) { $scope.form = { name: 'my name', surname: 'surname' } $scope.$watch('form', function(newVal, oldVal){ console.log('changed'); }); } 

这里是小提琴: http : //jsfiddle.net/Y8ByG/

我希望每次更改名称或姓氏时都会触发$ watchcallback,但不会发生。

什么是正确的方法来做到这一点?

作为第三个参数调用$watch作为true

 $scope.$watch('form', function(newVal, oldVal){ console.log('changed'); }, true); 

默认情况下,在比较JavaScript中的两个复杂对象时,将检查它们是否为“引用”相等,它会询问两个对象是否引用相同的东西,而不是“值”相等,它检查这些属性的值对象是平等的。

根据Angular文档 ,第三个参数是objectEquality

objectEquality == true ,根据angular.equals函数确定watchExpression的不等式。 为了保存对象的值以供以后比较,使用angular.copy函数。 因此,这意味着观看复杂的物体将会产生不良的记忆和性能影响。

form对象不变,只有name属性是

更新小提琴: http : //jsfiddle.net/ReuA8/1/

 function MyController($scope) { $scope.form = { name: 'my name', } $scope.changeCount = 0; $scope.$watch('form.name', function(newVal, oldVal){ console.log('changed'); $scope.changeCount++; }); } 

如果某人使用键 – >值对具有数据存储types的服务,则性能提示很less:

如果您有一个名为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 } }); }); 

你的代码不工作的原因是因为$watch默认是引用检查。 所以简而言之,确保传递给它的对象是新对象。 但在你的情况下,你只是修改表单对象的一些属性,而不是创build一个新的。 为了使它工作,你可以传递true作为第三个参数。

 $scope.$watch('form', function(newVal, oldVal){ console.log('invoked'); }, true); 

它将工作,但您可以使用$ watchCollection这将更有效,然后$ watch,因为$watchCollection将监视窗体对象的浅属性。 例如

 $scope.$watchCollection('form', function (newVal, oldVal) { console.log(newVal, oldVal); }); 

当你正在寻找表单对象的变化,最好的观察方法是使用
$watchCollection 。 请查看官方文档以了解不同的性能特点。 https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch

尝试这个:

 function MyController($scope) { $scope.form = { name: 'my name', surname: 'surname' } function track(newValue, oldValue, scope) { console.log('changed'); }; $scope.$watch('form.name', track); } 

对于任何想要对对象数组中的对象进行更改的人,这似乎适用于我(因为此页上的其他解决scheme没有):

 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); 

你必须改变$手表….

 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>