繁体   English   中英

Angular.js仅监视特定的对象属性

[英]Angular.js watch only on particular object property

基本上我想要这个http://plnkr.co/edit/3yfXbo1c0llO40HZ8WNP?p=preview但是当我改变东西时手表不会触发..

我知道这会奏效

$scope.$watch('stuff', function (newVal, oldVal) {
    console.log(oldVal, newVal);

}, true);

但是因为我想在手表内做一些总结而我不想不必要地循环或重新加总没有改变的值。

//编辑 - 请注意,plnkr示例只是从实际应用程序中提取,您可以在其中添加和删除行等等,例如从ng-repeat之外的另一个输入修改总数(某些事物和某些事物的总和)。 。

我不会做手表,因为你的阵列有多大,可能会非常费力。 相反,我只想创建一个过滤器:

HTML:

Sum of something is: {{ stuff | sum:'something' }}<br/>
Sum of somethingelse is: {{ stuff | sum:'somethingelse' }}

使用Javascript:

.filter("sum", function(){
    return function(input, params){
        var totalSum = 0;
        for(var x = 0; x < input.length; x++){
            totalSum += input[x][params];
        }
        return totalSum;
    }
})

plnkr: http ://plnkr.co/edit/p6kM3ampSuMXnwqcteYd?p =preview

在我为您的问题找到解决方案后,我到处都是微笑。 这个解决方案不仅要观察单个对象,而且还不会完成整个对象的完整循环以进行求和。

http://plnkr.co/edit/oPWobcLLtJlxs5vjTYyc?p=preview

app.controller('MainCtrl', function($scope) {
  $scope.stuff = STUFF;
  var i;
  $scope.sumOfSomething = 0;
  $scope.sumOfSomethingElse = 0;

  for(i=0;i < $scope.stuff.length;i++ ){
    $scope.$watch('stuff['+i+'].something', function (newVal,oldVal) {
      // happens when the watch is registered.
      if(oldVal === newVal){
        $scope.sumOfSomething += +newVal;
        return;
      }
      if(newVal){
        $scope.sumOfSomething += + (newVal - oldVal);
      }
    });

    $scope.$watch('stuff['+i+'].somethingelse', function (newVal,oldVal) {
      // happens when the watch is registered. 
      if(oldVal === newVal){
        $scope.sumOfSomethingElse += +newVal;
        return;
      }

      if(newVal){
        $scope.sumOfSomethingElse += + (newVal - oldVal);
      }

    });  
  }
});

顺便说一句,如果你在STUFF有大量的对象,我不知道这个解决方案会有多优化。 此外,如果STUFF的对象数量将发生变化,这将不会起作用。 我们基本上做的是使用角度的脏检查循环来为我们做总结。

还要注意watch监听器中newVal和oldVal的顺序。 你的订单错了。

由于$watch()采用角度表达式,因此您可以使用自定义观察器功能。 在您的情况下,观察更改的最简单方法是简单地将您感兴趣的所有字段相加,然后返回单个数字,这对于角度来说是好的和有效的,并且您的总和将准备好呈现。

var sumThings = function(obj, field) {
  var val = 0;
  obj.forEach(function(o) {
    val += parseInt(o[field]);
  });
  return val;
};

$scope.$watch(function() { return sumThings($scope.stuff, "something")}, function (newVal, oldVal) {    //console.log("watchExpression('something') fired!", oldVal, newVal);
  $scope.somethingSum = newVal;
});

$scope.$watch(function() { return sumThings($scope.stuff, "somethingelse")}, function (newVal, oldVal) {
  $scope.somethingelseSum = newVal;
});

基本上,通过做你的总结,你正在进行自己的脏检查。 如果您的对象比您在此处显示的更复杂$watch(STUFF, true)它将比$watch(STUFF, true)更有效。

您更新的plnkr: http ://plnkr.co/edit/d7CvERu3XGkub4l6f1yw?p = preview

好吧,如果我得到了它,你只是想总结somethingsomethingelse当他们改变内部对象。 并且如果更改位于其中一个内部对象中,则不希望循环遍历所有其他内部对象。

好吧,你的$watch没有因为没有stuff.property而被stuff.property ,并且没有类似stuff.*.something模式stuff.*.something

如果您知道从数组中推送或拉出对象的时刻,那么您可以在将每个$scope.$watch(object, function(){}, true)插入数组之前/之后应用单独的$scope.$watch(object, function(){}, true) 如果您不知道这一刻,那么您将需要$watch整个阵列,并且当发生更改时,运行所有注销功能并再次逐个$watch它们。

无论如何,现在浏览器中的循环非常快,除了你正在进行繁重的计算并且你有数百万个对象(本来会出现内存问题)你可能会对它很好。 因此,只有在您进行了非常繁重的计算(包括系统性能)时才需要单独$watch它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM