最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin2浏览0评论

I have an array of objects that I'm displaying in my Angular app using ng-repeat. I'm filtering out items using filter and the value of a search input. It works as expected. But, I have a "select all" / "deselect all" option and I only want to select the visibile items in the list (the ones that meet the current search criteria).

Without performing the same logic in my controller (i.e. using indexOf the search value on each of my objects), how can I tell which items are currently filtered out by ng-repeat/filter?

My view:

<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>

A function in my controller:

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

I have significantly simplified my code samples here for simplicity since this question doesn't need much more detail. Is there a way to do what I'm thinking or do I need to perform the "search" again?

I have an array of objects that I'm displaying in my Angular app using ng-repeat. I'm filtering out items using filter and the value of a search input. It works as expected. But, I have a "select all" / "deselect all" option and I only want to select the visibile items in the list (the ones that meet the current search criteria).

Without performing the same logic in my controller (i.e. using indexOf the search value on each of my objects), how can I tell which items are currently filtered out by ng-repeat/filter?

My view:

<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>

A function in my controller:

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

I have significantly simplified my code samples here for simplicity since this question doesn't need much more detail. Is there a way to do what I'm thinking or do I need to perform the "search" again?

Share Improve this question asked Jun 8, 2015 at 20:17 amlyhammamlyhamm 1,1502 gold badges20 silver badges37 bronze badges 2
  • Check out @azium 's comment on my answer. You'll probably want to use angular.forEach – allienx Commented Jun 8, 2015 at 20:40
  • Of course, I was just throwing it out there as a quick example! Thanks. – amlyhamm Commented Jun 9, 2015 at 12:37
Add a comment  | 

3 Answers 3

Reset to default 20

You can bind the filtered array to another scope variable in your view, then access that in your controller.

View:

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

Controller:

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

Your issue is that ng-repeat is scope isolated. As a result you can't refer to the internal list that is being managed by ng-repeat from your controller/directive.

As a result there are 2 options

  1. Bind the filtered list to ng-repeat from your controller/directive, so you maintain the filtered list.

    //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. Perform the filter again in your controller/directive

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

Angular filters create a new array. So in order to perform an action on the filtered items you're going to have to capture the new array.

Something like:

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

If you don't want to filter twice you'll have to filter the array yourself every time searchValue changes and ng-repeat over that filtered array, ng-change is useful in that case.

发布评论

评论列表(0)

  1. 暂无评论