Javascript 当我';我用同样的属性过滤?

Javascript 当我';我用同样的属性过滤?,javascript,angularjs,Javascript,Angularjs,我如何做到这一点: $scope.$watch('item.completed', function(to, from){ … 与此同时: <li ng-repeat="item in items | filter:{completed: true}" ng-controller="ItemCtrl"> … … 实时plunker示例: 当前,当我更改项对象的completed属性时,$watch()未触发 我怀疑这与过滤器弄乱了对象属性的引用有关,但我如何才能做到这一点呢?我

我如何做到这一点:

$scope.$watch('item.completed', function(to, from){ …
与此同时:

<li ng-repeat="item in items | filter:{completed: true}" ng-controller="ItemCtrl"> …
  • 实时plunker示例:

    当前,当我更改
    对象的
    completed
    属性时,
    $watch()
    未触发


    我怀疑这与过滤器弄乱了对象属性的引用有关,但我如何才能做到这一点呢?我也尝试过
    $watch(…,…,true)
    $watchCollection()
    但两者都没有任何效果。

    如果使用ng show而不是筛选,您应该能够启动watch函数

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

  • 您可以侦听scope destroy事件并从事件对象获取值:

    .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);
        });
      }]);
    

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

  • 完全忘了手表吧。只需调用
    ng change
    上的函数即可输入复选框:
  • 通过
    $scope.$watch('items',listener,true)
    在items数组本身上创建深度监视。第三个参数为
    true
    将导致使用检查,然后您可以比较数组的前后状态,并记录每次更改的内容:

  • 这两种方法都不完全是一种可以在列表中为您提供特定更改项的
    手表,但我认为您可以通过这些途径获得最终需要做的事情。

    这是一种黑客方式,但我猜它可以满足OP的要求:

    这也证明了乔纳斯和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);
      }]);
    

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

    我认为那里的绑定出了问题。对第一个列表的任何更改也应影响第二个列表,因为它们应绑定到相同的
    $scope.items
    对象。过滤是否以某种方式破坏了绑定?我认为这与列表上的过滤器是由您正在监视的属性驱动的这一事实有关。当您取消选中列表中的某个项目时,它将不再是正在监视的列表的成员。是的,这与复选框将项目从筛选器中拉出有关。如果您正在监视不驱动筛选器的第二个属性,则监视将起作用:当使用筛选器从ng repeat中删除项时,它们的作用域将被销毁,因此您基本上不再监视它们。@jdmcnair示例之所以起作用,是因为取消选中时元素不会被删除,而不是因为他使用的是不同的propertyTrue,但这是一个黑客,在我的情况下,我需要能够计算过滤结果(例如filteredItem=(item | filter:{completed:true})
    )啊,好的。如果是这样的话,那么意外地有两个项目列表是一个范围问题。上面Josep的回答显示了一种更好的构建结构的方法,使两个控制器都能处理单个项目集。为了快速验证,只需将两个列表放在同一个控制器下即可。如下所示:
    • {{{item.name}

    • {item.name}
    +1,如果OP真的想通过在ng repeated items controller上移除的项目上放置手表来解决此问题,这可能是唯一的解决方案(尽管销毁时其值始终为
    true
    。lol)。但我还是不明白为什么会有一块手表我同意。但是,即使smth不是一个好的解决方案,理解为什么smth不起作用总是很好的solution@PSL:为了便于辩论
    ng click
    对键盘按键不起作用(但是
    ng change
    会起作用)。我的示例使用简化的代码;在实际使用中,被监视的值可能是由用户直接输入以外的内容生成的。