AngularJS忽略观察对象中的键或覆盖$ watch侦听器

Bar*_*amo 5 javascript angularjs angularjs-scope

我正在深深地看着一个绑定了多个控件的属性:

$scope.$watch('config', function(){}, true);
Run Code Online (Sandbox Code Playgroud)

配置本身包含各种参数:

  • 规模
  • 点
  • 聚集
  • 当前

我希望忽略特定控件和特定函数更改时的比例更改.

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


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

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);
Run Code Online (Sandbox Code Playgroud)

Jos*_*off 7

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

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

没有Lodash [黑名单属性]:

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

没有Lodash [白名单属性]:

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

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


jlb*_*jlb 2

据我所知,还没有,但一个简单的检查就可以解决问题:

$scope.$watch('config', function(newValue, oldValue){
  if (newValue.scale == oldValue.scale) {
    // ignore this
    return;
  }
  // continue...
}, true);
Run Code Online (Sandbox Code Playgroud)

  • 如果有不止一个属性并且至少有两个被更改,则该算法会错过一些更改,因为键“scale”也发生了更改。 (4认同)