当我'm通过相同的属性进行过滤

How can I watch a property for changes within a filtered array of objects when I'm filtering by that same property?

本文关键字:属性 过滤 当我      更新时间:2023-09-26

如何做到这一点:

$scope.$watch('item.completed', function(to, from){ …

与此结合:

<li ng-repeat="item in items | filter:{completed: true}" ng-controller="ItemCtrl"> …

Live plunker示例:http://plnkr.co/edit/pdFkEmxyqrzS6mc2AYo2?p=preview

当前,当我更改item对象的completed属性时,$watch()不会激发。

我怀疑这与过滤器扰乱对象属性的引用有关,但如果不是这样,我怎么能做到呢?我也试过$watch(…, …, true)$watchCollection(),但都没有效果。

您可以监听作用域销毁事件并从事件对象中获取值:

.controller('ItemCtrl', ['$scope', function($scope){
    $scope.$on('$destroy', function(o){log(o.targetScope.item.name + '(' + o.targetScope.item.completed + '):destroyed')});
    $scope.$watch('item.completed', function(to, from){
      log(from + ' --> ' + to);
    });
  }]);

我仍然不完全确定我是否理解最终目标。我想你是说你希望能够在筛选列表中的项目发生更改时进行日志记录。我能想出几个不完美的方法。

  1. 把手表忘得一干二净。只需在ng-change上为复选框输入调用一个函数:http://plnkr.co/edit/IeAt4a31So7zjMJzptIp?p=preview
  2. 通过$scope.$watch('items', listener, true)对items数组本身创建深度监视。第三个参数true将导致使用对象相等检查,然后您可以比较数组的前后状态,并记录每次更改的内容:http://plnkr.co/edit/gg5DPWJhx8syhNhelFOT?p=preview

两者都不是一个watch,它在列表中为您提供了一个特定的更改项目,但我认为您可以通过这些途径获得最终需要做的事情。

如果使用ng-show而不是过滤,则应该能够启动watch函数。

<li ng-repeat="item in items" ng-show="{{item.completed}}" ng-controller="ItemCtrl">

这是一种很有技巧的方法,但我想它可以满足OP的要求:

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

这也证明了乔纳斯纳斯和PSL是完全正确的。

这个想法是在控制器中做到这一点:

  .controller('ItemsCtrl', ['$scope', function($scope){
    $scope.items = [
      {name: 'item 1', completed: true},
      {name: 'item 2', completed: true},
      {name: 'item 3', completed: true},
      {name: 'item 4', completed: false},
      {name: 'item 5'},
      {name: 'item 6', completed: true},
    ];
    $scope.itemsToWatch=[];
    $scope.watchMe = function(item){
      var myIdx = $scope.items.indexOf(item);
      if($scope.itemsToWatch.indexOf(myIdx)==-1){
        $scope.itemsToWatch.push(myIdx);
        $scope.$watch('items[' + myIdx + '].completed', function(to, from){
          log(from + ' --> ' + to);
        });
      }
    };
  }])
  .controller('ItemCtrl', ['$scope',function($scope){
      $scope.$parent.watchMe($scope.item);
  }]);

我不认为我会在真正的应用程序中编写这样的代码,但找到解决问题的方法很有趣,在这个过程中我学到了一些东西。