How to $watch multiple variables?

后端 未结 4 1105
天命终不由人
天命终不由人 2021-02-02 17:36

I do have two $scope variables. They are called $scope.image and $scope.titleimage.

Basically the store the same type of contents.

相关标签:
4条回答
  • 2021-02-02 18:22

    $watch method accepts a function as first parameter (beside a string). $watch will "observe" the return value of the function and call the $watch listener if return value is changed.

    $scope.$watch(
      function(scope){
        return {image: scope.image, titleImage: scope.titleImage};
      }, 
      function(images, oldImages) {
        if(oldImages.image !== images.image){
          console.log('Image changed');
        }
        if(oldImages.titleImage !== images.titleImage){
          console.log('titleImage changed');
        }
      }, 
      true
    ); 
    

    Also you might observe a concatenated value, but that doesn't let you know which one of the observed values actually changed:

    $scope.$watch('image + titleImage',
      function(newVal, oldVal) {
        console.log('One of the images have changed');
      }
    ); 
    

    And you can also watch an array of scope variables:

    $scope.$watch('[image, titleImage]',
      function(images, oldImages) {
        if(oldImages[0] !== images[0]){
          console.log('Image changed');
        }
        if(oldImages[1] !== oldImages[1]){
          console.log('titleImage changed');
        }
      },
      true
    ); 
    
    0 讨论(0)
  • 2021-02-02 18:25

    Use computed and return multiple variables in an array that you want to listen to that should execute the same function.

    computed: {
      photo () {
        return [this.image, this.title]
      }
    },
    watch: {
      photo () {
        console.log('changed')
      }
    },
    
    0 讨论(0)
  • 2021-02-02 18:29

    The correct answer was found here:

    https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watchCollection

    "for arrays, this implies watching the array items; for object maps, this implies watching the properties"

    Example:

    $scope.$watchCollection(function () {
        return {t : ctrl.time, d : ctrl.date};
    }, function(value) {
        ctrl.updateDateTime();
    });
    
    0 讨论(0)
  • 2021-02-02 18:32

    Stewie's suggestions will work. But there are a thousand ways to skin this cat. I'd submit that if you're watching two separate values, there's nothing wrong with setting up two watches for them with a shared function between them:

    functional programming to the rescue!

    Using functions to create functions is awesome.

    function logChange(expr) {
       return function(newVal, oldVal) {
          console.log(expr+ ' has changed from ' + oldVal + ' to ' + newVal);
       };
    }
    
    $scope.$watch('image', logChange('image'));
    $scope.$watch('titleImage', logChange('titleImage'));
    

    OR... you could even wrap the watch setup in it's own function (much less exciting, IMO):

    function logChanges(expr) {
       $scope.$watch(expr, function(newVal, oldVal) {
          console.log(expr+ ' has changed from ' + oldVal + ' to ' + newVal);
       });
    };
    
    logChanges('image');
    logChanges('titleImage');
    

    .. but I have a thousand of them, you say?

    //assuming the second function above
    angular.forEach(['image', 'titleimage', 'hockeypuck', 'kitchensink'], logChanges);
    
    0 讨论(0)
提交回复
热议问题