AngularJS: Count Filtered Items

前端 未结 4 1707
醉话见心
醉话见心 2020-12-31 03:31

I am showing subsets of a list if a checkbox is checked. I would like to replace the X next to the checkbox with the count of the list matching the selection criteria. I hav

相关标签:
4条回答
  • 2020-12-31 04:04

    To find the count objects, I use <scope_obj>.length in the .html template.

    Here's my controller:

    conciergeControllers.controller('GuestMsgPreviewCtrl', ['$scope', 'GuestMessages',
        function($scope, GuestMessages) {
        $scope.guests = GuestMessages.query();
    }]);
    

    And template (each guest object has a messages attribute that is an array object, so .length returns the number of nested message objects:

    <ul ng-repeat="guest in guests">
      <li>[[ guest.messages.length ]]</li>
    </ul>
    
    0 讨论(0)
  • 2020-12-31 04:05

    Assuming your list of people is in data variable and you filter people using query model, the following code will work for you:

    • Number of visible people: {{(data|filter:query).length}}
    • Total number of people: {{data.length}}

    summary

    {{data.length}} - prints total number of people

    {{(data|filter:query).length}} - prints filtered number of people

    0 讨论(0)
  • 2020-12-31 04:13

    Possible solution 1: Inline

    You could actually save a reference to the filtered results in a variable: h in filtered.marvel = (heroes | filter:{comic:'Marvel'}), which you could use like so: filtered.marvel.length.

    See: Plunkr

    Possible solution 2: In the controller

    You could also move this code to your controller:

    $scope.filteredHeroes.marvel = $filter('filter')($scope.heroes, {comic:'Marvel'});

    , which you could use by ng-repeat="hero in filteredHeroes.marvel"

    and {{filteredHeroes.marvel.length}}

    (Don't forget to add $filter as a controller dependency)

    See: Plunkr

    0 讨论(0)
  • 2020-12-31 04:17

    You could set that count in the view model itself while binding the data or just have a method on the scope that returns the count.

    app.controller('MainController', function($scope, filterFilter){
       ....
        $scope.getCount = function(strCat){
          return filterFilter( $scope.heroes, {comic:strCat}).length;
        }
        ...
    });
    

    and use it as:-

      Marvel [{{getCount("Marvel")}}]
      .....
      DC Comics [{{getCount("DC")}}]
    

    Plnkr

    If the list is non changing when you are on the page i would suggest finding out the length and binding it to a property in the view model itself, and use it in the view.

     //Set your data model
      $scope.cbMarvel = {value:true, count:getCount('Marvel')};
      $scope.cbDCComics = {value:true, count:getCount('DC')};
    

    and in your view

       <input type="checkbox" ng-model="cbMarvel.value"/> Marvel [{{cbMarvel.count}}]
    

    Plnkr2

    If your dataset is huge, instead of using filter inside the getCount, use a forEach and populate the count for each type at once.


    Infact you do not need a filter at all, it seems inefficient to iterate through the same list using a filter in your case. Your's is a static list so categorize it in the controller itself.

    var comics = $scope.comics  = {}; //Dictionary of comics
      //Create the collection here.
      angular.forEach(heroes, function(itm){
        if(!comics[itm.comic]){
         comics[itm.comic] = {name:itm.comic, value:true, count:1, items:[itm] };
         return;
        }
    
        comics[itm.comic].count++; //Incr count
        comics[itm.comic].items.push(itm); //push specific item
      });
    

    and remove all the filters in your view and do:-

        <div ng-repeat="h in comics.Marvel.items" ng-show="comics.Marvel.value">
            {{ h.name}} - {{h.comic}}
        </div>
        <div ng-repeat="h in comics.DC.items" ng-show="comics.DC.value">
          {{ h.name}} - {{h.comic}}
        </div>
    

    Plnk3 - the better one

    0 讨论(0)
提交回复
热议问题