Watch entire object (deep watch) with AngularJS

2020-08-26 05:17发布

问题:

This is a scope angular-resource variable / object that represents a form data:

    $scope.form = {
              name: 'bob', 
              email: 'bob@bobs.com'
    }

There is the way I watch where my name variable is changed.

    $scope.$watch('form.name', function(newVal) {
        if(newVal) {
            alert(newVal)
        }
    });

What would be a way to watch if any of fileds was changed- name, email, or whatever scope.form may have?

My purpose to make my form 'save' disabled or enabled depending on that fact that user has changed something on the form.

回答1:

There is a third parameter of $watch() that will make it check for object equality (deep watch).

  $scope.$watch('form', function(newVal) { //watch the whole object
        if(newVal) {
            alert(newVal);
        }
    }, true); //pass "true" here.

To further complete my answer, both of these approaches produce the same result in this case: Live demo here (click). but $watchCollection is shallow and will not watch anything nested for changes.

  $scope.$watch('form', function(newForm, oldForm) {
    console.log(newForm.name);
  }, true);

OR: (not a deep watch)

  $scope.$watchCollection('form', function(newForm, oldForm) {
    console.log(newForm.name); 
  });


回答2:

Since AngularJS 1.1.x the preferred way of watching multiple values in an array or properties of an object is $watchCollection http://docs.angularjs.org/api/ng.$rootScope.Scope

$scope.$watchCollection('form', function(newValues, oldValues) {
    console.log('*** Watch has been fired. ***');
    console.log('New Names :', newValues);}
);