【问题标题】:How can I watch a filtered collection in Angular.JS?如何在 Angular.JS 中观看过滤后的集合?
【发布时间】:2016-01-16 18:56:51
【问题描述】:

每当过滤的集合发生更改时,我都会尝试触发事件。过滤后的列表附加到 ng-repeat 中的非过滤列表。

<tr ng-repeat="item in $scope.filtered = (vm.list | filter:vm.searchText) | limitTo:vm.limit:vm.begin">

这是我想要触发的事件:

 $scope.$watchCollection('filtered', function () {
            alert($scope.filtered.length);
        }, true);

它在页面第一次加载时触发一次,在我的 ajax 调用填充 vm.list 之前,所以警报显示为 0,但是在填充 vm.list 之后它应该再次触发,并且每次对 vm.searchText 的更改都会导致对 $scope.filtered 的更改,但不是。

我也尝试过像这样制作 $watchCollection 方法:

$scope.$watchCollection('filtered', function (newList, oldList) {
            alert(newList.length);
        });

但结果相同。

我也尝试按照here 的建议做,结果是这样的:

<tr ng-repeat="item in catchData((vm.list | filter:vm.searchText)) | limitTo:vm.limit:vm.begin">

$scope.catchData = function (filteredData) {
            alert(filteredData.length);
            return filteredData;
  }

这似乎一开始就解决了。它现在在 API 调用填充列表时触发,并在 searchText 导致过滤列表更改时再次触发。不幸的是,它使得更改 limitTo 过滤器上的开始选项不再起作用。更改限制选项仍然有效,但不是开始。更改开始仍然可以使用 $watchCollection 方法。

有人有什么想法吗?

【问题讨论】:

  • 也开始监视,您需要 digest() 并且由于您正在使用警报,因此您必须手动调用 apply() 方法,这将导致 digest() 运行并因此运行您的 watcher。跨度>
  • @AayushiJain 请为此引用文档。从未在手表中使用过$apply()$digest() 来检测角度范围内的任何东西
  • item in $scope.filtered 无效...视图中没有$scope ...应该是item in vm.filtered =(....) 并且手表在使用controllerAs时需要使用函数
  • 用一点数据创建一个简单的 plunker 演示
  • 你能提供你的控制器代码吗?

标签: javascript angularjs


【解决方案1】:

当您在视图中创建一些变量时,它会作为属性添加到当前范围。因此,在您的情况下,您创建 $scope.filtered,并将其添加到当前范围。
要让它在手表中,你只需要使用相同的声明

$scope.$watchCollection('$scope.filtered', function () {
    console.log($scope.$scope.filtered.length)
}

但最好不要使用像$scope这样的变量名,以免与角度变量混淆。

所以,你可以简单地改变它:过滤

angular.module('app', [])
  .controller('ctrl', function($scope) {
    $scope.$watchCollection('$scope.filtered', function(nval) {
      if(!nval) return; //nval - new value for watched variable
      console.log('as $scope.filtered in view', $scope.$scope.filtered.length);
    }, true);
    $scope.$watchCollection('filtered', function(nval) {
      if(!nval) return; //nval - new value for watched variable
      console.log('as filtered in view', $scope.filtered.length);
    }, true);
  })
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  <input type="text" data-ng-model="search" />
  <h3>as $scope.filtered</h3>
  <div ng-repeat="item in $scope.filtered = ([11,12,23]| filter:search)">item_{{item}} from {{$scope.filtered}}</div>
  <h3>as filtered</h3>
  <div ng-repeat="item in filtered = ([11,12,23]| filter:search)">item_{{item}} from {{filtered}}</div>
</div>

【讨论】:

  • 我是使用 $scope 的新手,我阅读的文档听起来好像只有在控制器中声明为 $scope 属性的变量才能被观看。显然这完全不是真的。所以我注释掉了 $scope.filtered = []; 的声明并将我的 ng-repeat 更改为:。然后它完美地工作了。非常感谢。
  • @SurgeBinder,您可以查看任何$scope 字段,无论何时何地声明,也可以将函数作为watchExpression 参数传递,因此您不仅可以查看$scope 字段。在doc and samples中查看更多信息
【解决方案2】:

您将需要使用函数来返回过滤后的列表并将对象相等设置为 true。

$scope.$watch(function () {
  return $scope.filtered;
}, function (newList) {
  alert(newList.length);
}, true);

【讨论】:

    猜你喜欢
    相关资源
    最近更新 更多
    热门标签