【问题标题】:How to $watch multiple variables?如何 $watch 多个变量?
【发布时间】:2013-07-07 05:17:18
【问题描述】:

我确实有两个 $scope 变量。它们被称为$scope.image$scope.titleimage

基本上存储相同类型的内容。我想现在跟踪其中任何一个更新。但到目前为止,我无法弄清楚如何在单个 $scope.$watch() 回调中跟踪两个变量。

// How can I watch titleimage here as well?
$scope.$watch('image', function(media) {
    console.log('Media change discoverd!');
}); 

【问题讨论】:

标签: angularjs angularjs-scope


【解决方案1】:

$watch 方法接受一个函数作为第一个参数(在字符串旁边)。 $watch 将“观察”函数的返回值,并在返回值发生变化时调用 $watch 监听器。

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

您也可能会观察到一个连接值,但这不会让您知道观察到的值中的哪一个实际发生了变化:

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

您还可以查看范围变量数组:

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

【讨论】:

  • 你不是说oldImages.titleImage !== images.titleImage吗? (你有两次oldImages。)
  • 第一种返回对象的方法最好!干净简洁
  • 在您的第一个示例的底部,我几乎没有看到真正的小参数。这使得新旧对象之间的比较成为深度比较。添加后工作正常:)
  • @Trojan 我已编辑,但尚未反映...等待同行评审
【解决方案2】:

Stewie 的建议会奏效。但是有一千种方法可以剥这只猫的皮。我认为,如果您正在观看两个单独的值,那么为它们设置两个手表并在它们之间使用共享功能并没有错:

函数式编程助你一臂之力!

使用函数创建函数很棒。

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

或者...您甚至可以将手表设置封装在它自己的功能中(更不令人兴奋,IMO):

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

logChanges('image');
logChanges('titleImage');

.. 但我有一千个,你说?

//assuming the second function above
angular.forEach(['image', 'titleimage', 'hockeypuck', 'kitchensink'], logChanges);

【讨论】:

    【解决方案3】:

    使用计算并返回一个数组中的多个变量,这些变量应该执行相同的函数。

    computed: {
      photo () {
        return [this.image, this.title]
      }
    },
    watch: {
      photo () {
        console.log('changed')
      }
    },
    

    【讨论】:

      【解决方案4】:

      在这里找到正确答案:

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

      "对于数组,这意味着查看数组项;对于对象映射,这意味着查看属性"

      例子:

      $scope.$watchCollection(function () {
          return {t : ctrl.time, d : ctrl.date};
      }, function(value) {
          ctrl.updateDateTime();
      });
      

      【讨论】:

        猜你喜欢
        • 2015-03-03
        • 1970-01-01
        • 2015-02-23
        • 2020-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-18
        • 2019-06-16
        相关资源
        最近更新 更多