How to use a $watchGroup with object equality or deep-watch the properties in the group?

后端 未结 3 536
感动是毒
感动是毒 2020-12-15 07:14

I want a directive to re-render HTML whenever three scope variables have changed. The first two are just integers, the third is an array.

We have $watchGroup

相关标签:
3条回答
  • 2020-12-15 07:34

    Well it seems like watchGroup does not support a deep watch. So probably you can do a hack, by registering an anonymous deep watcher with array of values being passed in from the watch function.

    $scope.$watch(function(){
         return ['number1','number2','myArray'].map(angular.bind($scope, $scope.$eval));
      }, function(newV){
          console.log(newV);
      },true);
    

    Demo

    or just add this function as utility function on the rootScope and access it from any inherited scopes.

    .run(function($rootScope){
      $rootScope.deepWatchGroup = function(exp, callback){
        if(!angular.isArray(exp) || !thisScope.$watch) return; //Or log some error if array is not passed in or the context is not really a scope object
    
       var thisScope = this, //get scope
            evalFunc = angular.bind(thisScope, thisScope.$eval); //and a bound eval func
    
         thisScope.$watch(function(){
            return exp.map(evalFunc); //return array of evaluated values
         }, callback,true);
       }
    });
    

    and from your controller do:

    $scope.deepWatchGroup(['number1','number2','myArray'],function(newV){
      console.log(newV);
    });
    

    Demo

    0 讨论(0)
  • 2020-12-15 07:43

    I also had the same problem as yours.

    My solution to this deep watchgroup problem is:

    // Create new object to watch different types of objects
    var objectToBeWatch = {
        number1: number1, 
        number2: number2,
        myArray: myArray
    };
    
    $scope.$watch(
        function () {
            return objectToBeWatch;
    }, callback, true);
    

    I hope this helps!

    0 讨论(0)
  • 2020-12-15 07:54

    If you want to watch an array of string expressions (i.e. you do not need to watch functions, which both $watchGroup and PSL's solution can handle), here is an alternative:

    $scope.$watch('[number1, number2, myArray]', callback, true);
    

    And if you want to make a utility function for that similar to PSL's:

    .run(function($rootScope){
      $rootScope.deepWatchGroup = function(watchExpressions, listener){
        this.$watch('[' + watchExpressions + ']', listener, true);
      }
    });
    
    0 讨论(0)
提交回复
热议问题