6

我正在深入观察绑定到多个控件的属性:

$scope.$watch('config', function(){}, true);

配置本身包含各种参数:

  • 规模
  • 观点
  • 聚集体
  • 当前的

当特定控件和特定功能更改比例时,我想忽略比例变化。

有没有办法忽略特定属性或覆盖手表是特定情况?


现在这就是我正在做的事情:

dataChange 现在仅在某些更改时触发,在这种情况下,当其他属性(而不是缩放)发生更改时。

为了禁用特定缩放案例的 dataChange,我只是将其分配给其余案例。

我使用 Switch 而不是 if/else 只是因为它更具描述性并且易于扩展以适应更多情况。

  $scope.$watch('config', function(n,o,scope){
   $scope.config = n;
    if (n != o) {
     switch(true){
      case n.zoom != o.zoom:
      break;

      default:
         $scope.dataChange($scope.dataTable);              
      };
    }
}, true);
4

3 回答 3

7

我不喜欢这些答案中的任何一个。$watch 的第一个参数是要监视的内容,它接受属性名称作为字符串,或者返回值的函数。只需使用一个函数并返回您想要观看的值。在这里,我使用 lodash JS 库 $watch 一个基于真实对象的新对象,但属性被剥离:

$scope.$watch(function() {
  return _.omit($scope.config, 'scale');
}, function(oldVal, newVal) {
  console.log(oldVal, newVal);
});

没有 Lodash [黑名单属性]:

$scope.$watch(function() {
  var myConfig = Angular.copy(config);
  delete myConfig.scale;
  return myConfig;
}, function(oldVal, newVal) {
  console.log(oldVal, newVal);
});

没有 Lodash [白名单属性]:

$scope.$watch(function() {
  return {
     point: $scope.config.point,
     aggregates: $scope.config.aggregates,
     current: $scope.config.current
  };
}, function(oldVal, newVal) {
  console.log(oldVal, newVal);
});

在我看来,其他答案不是“角度方式”。这种方法不仅比其他混乱的答案更简洁,而且还避免了在 $watch 触发时执行冗余对象比较。请记住,其他答案会产生两次对象比较的成本,一次是针对 Angular 代码中的 $watch 本身,然后您会在回调函数中产生“自制”对象​​比较的成本。我的方法确保对象比较只在 Angular 代码中发生一次,方法是在将对象输入 $watch 进行比较之前剥离不需要的属性。

于 2015-08-08T16:59:23.380 回答
2

据我所知,但一个简单的检查就可以了:

$scope.$watch('config', function(newValue, oldValue){
  if (newValue.scale == oldValue.scale) {
    // ignore this
    return;
  }
  // continue...
}, true);
于 2013-05-16T13:36:02.730 回答
0

更好的解决方案可以是该功能;

$scope.equalsAdvanced=function (sourceObject, targetObject, ignoredProperties)
                 {
                     // direct compare if there is no ignored properties
                     if (!ignoredProperties || (angular.isArray(ignoredProperties) && ignoredProperties.length<=0)) {
                         return angular.equals(sourceObject, targetObject);
                     }

                     // take the original ignored property list to a new variable
                     var ignoredPropertyList=ignoredProperties;

                     // make it array if it is not
                     if (!angular.isArray(ignoredPropertyList)) {
                         var list = [];
                         list.push(ignoredPropertyList);
                         ignoredPropertyList = list;
                     }

                     // compare property list
                     for (propertyName in sourceObject) {
                         if (ignoredPropertyList.indexOf(propertyName) >= 0)
                             continue;

                         var sourceValue = sourceObject[propertyName];
                         var targeValue = targetObject[propertyName];

                         if (!angular.equals(sourceValue, targeValue))
                             return false;
                     }

                     return true;
                 };

您可以查看小提琴上的示例代码:http: //jsfiddle.net/tursoft/DpEwV/4/

这可能比以前更好;

代码:

    // service
    myApp
        .service("utils", function()
         {
             self=this;

             // watchAdvanced =====================
               self.$watchAdvanced = function ($scope, exp, ignoredProperties, callback)
                {
                    $scope.$watch(exp, function (newValue, oldValue) {
                        if (self.equalsAdvanced(newValue, oldValue, ignoredProperties))
                            return;

                        callback(newValue, oldValue);
                    }, true);
                }

                 // equalsAdvanced =====================
                 self.equalsAdvanced=function (sourceObject, targetObject, ignoredProperties)
                 {
                     // direct compare if there is no ignored properties
                     if (!ignoredProperties || (angular.isArray(ignoredProperties) && ignoredProperties.length<=0)) {
                         return angular.equals(sourceObject, targetObject);
                     }

                     // take the original ignored property list to a new variable
                     var ignoredPropertyList=ignoredProperties;

                     // make it array if it is not
                     if (!angular.isArray(ignoredPropertyList)) {
                         var list = [];
                         list.push(ignoredPropertyList);
                         ignoredPropertyList = list;
                     }

                     // compare property list
                     for (propertyName in sourceObject) {
                         if (ignoredPropertyList.indexOf(propertyName) >= 0)
                             continue;

                         var sourceValue = sourceObject[propertyName];
                         var targeValue = targetObject[propertyName];

                         if (!angular.equals(sourceValue, targeValue))
                             return false;
                     }

                     return true;
                 };
         });

用法:

utils.$watchAdvanced($scope, "user", ["_State", "ID"], function(newValue, oldValue)
                                   {                                       
                                       $scope.changeCount+=1;
                                       $scope.logs.push($scope.changeCount + ": User object is changed!");
                                   }, true);

小提琴的源代码:http: //jsfiddle.net/tursoft/5rLfr/2/

于 2014-04-08T09:24:42.390 回答