使用ng-repeat和filter,如何分辨哪些项是可见的

Using ng-repeat and filter, how to tell which items are visible?

本文关键字:ng-repeat filter 使用      更新时间:2023-09-26

我有一个对象数组,我使用ng-repeat在我的Angular应用程序中显示。我使用filter和搜索输入的值过滤掉项目。它像预期的那样工作。但是,我有一个"选择全部"/"取消选择全部"选项,我只想选择列表中可见的项(符合当前搜索条件的项)。

没有在我的控制器中执行相同的逻辑(即使用indexOf对我的每个对象的搜索值),我怎么能告诉哪些项目目前被ng-repeat/filter过滤掉?

我的观点:

<input type="text" ng-model="searchValue">
<input type="checkbox" ng-model="checkAll" ng-change="toggleAll()">
<tr ng-repeat="item in items | filter:searchValue">
    <td>{{item.id}}</td>
    <td>{{item.name}}</td>
</tr>

我的控制器中的一个函数:

$scope.toggleAll() {
     for(var i in $scope.items){
         // how can I tell if this item is filtered out in the view?
     }
}

为了简单起见,我已经大大简化了这里的代码示例,因为这个问题不需要更多的细节。是否有一种方法可以做我在想什么,或者我需要再次执行"搜索"?

你可以将过滤后的数组绑定到视图中的另一个作用域变量,然后在控制器中访问它。

视图:

<tr ng-repeat="item in filteredItems = (items | filter:searchValue)">
  ...
</tr>

控制器:

$scope.toggleAll = function () {
  angular.forEach($scope.filteredItems, function (item) {
    // do stuff
  })
}

您的问题是ng-repeat是范围隔离的。因此,你不能从控制器/指令中引用ng-repeat管理的内部列表。

因此有两个选项

  1. 将过滤列表绑定到控制器/指令中的ng-repeat,这样你就可以维护过滤列表。

    //in your controller
    $scope.filteredItems = $filter('yourFilter')($scope.items,$scope.searchText);
    $scope.$watch('searchText', function(newValue){
       $scope.filteredItems = $filter('yourFilter')($scope.items, newValue);
    });
    //in your view
    <tr ng-repeat="item in filteredItems">
        <td>{{item.id}}</td>
        <td>{{item.name}}</td>
    </tr>
    
  2. 在控制器/指令中再次执行过滤器

    $scope.toggleAll() {
        var items = $filter('yourFilter')($scope.items, $scope.searchText);
        for(var i in items){
           //set your selected property
        }
    }
    

Angular过滤器创建一个新的数组。因此,为了对过滤后的项目执行操作,您必须捕获新数组。

类似:

$scope.toggleAll() {
  var filteredItems = $filter('filter')($scope.items, $scope.searchValue);
  for(var i in filteredItems) {
    ...
  }
}

如果你不想过滤两次,你必须在每次searchValueng-repeat变化时自己过滤数组,ng-change在这种情况下是有用的