AngularJS:计算过滤的项目 [英] AngularJS: Count Filtered Items

查看:23
本文介绍了AngularJS:计算过滤的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果选中复选框,我将显示列表的子集.我想用与选择条件匹配的列表计数替换复选框旁边的 X.我有一个 plunker,除了计算子集这里.

我的控制器看起来像这样:

var app = angular.module('app', []);app.controller('MainController', function($scope){$scope.cbMarvel = 真;$scope.cbDCComics = true;$scope.heroes = [{编号:1,name: '钢铁侠',fname: '托尼',lname: '斯塔克',地点:斯塔克塔",漫画:《漫威》},{编号:2,name: '蝙蝠侠',fname: '布鲁斯',lname: '韦恩',地点:蝙蝠洞",漫画:'DC'},{编号:3,name: '超人',fname: '克拉克',lname: '肯特',位置:'大都会',漫画:'DC'},{编号:1,name: '夜魔侠',fname: '杰克',lname: '默多克',地点:'法庭房间',漫画:《漫威》},{编号:5,name: '闪光',fname: '巴里',lname: '艾伦',位置:'Speedline',漫画:'DC'},{编号:6,name: '绿巨人',fname: '布鲁斯',lname: '横幅',位置:实验室",漫画:《漫威》},{编号:7,name: '鹰眼',fname: '克林特',lname: '巴顿',位置:'巢',漫画:《漫威》},{编号:8,name: '雷神',fname: '唐纳德',lname: '布莱克',位置:'Asgard',漫画:《漫威》}];});

我的观点是这样的:

<html ng-app="app"><头><link data-require="bootstrap@*" data-semver="3.2.0" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.css"/><link data-require="bootstrap-css@*" data-semver="3.2.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"/><script data-require="bootstrap@*" data-semver="3.2.0" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.js"></脚本><script data-require="jquery@2.0.3 current" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"><<;/脚本><script data-require="angular.js@1.2.20" data-semver="1.2.20" src="https://code.angularjs.org/1.2.20/angular.js"></脚本><script data-require="angular-ui-bootstrap@*" data-semver="0.11.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.min.js"></script><link rel="stylesheet" href="style.css"/><script src="script.js"></script><body ng-controller="MainController"><字段集><legend>评论日志</legend><div class="row"><div class="col-md-4"><input type="checkbox" ng-model="cbMarvel"/>奇迹 [X]

<div class="col-md-4">&nbsp;</div><div class="col-md-4"><input type="checkbox" ng-model="cbDCComics"/>DC漫画 [X]

<div class="row">&nbsp;</div><div class="row col-md-10"><div ng-if="heroes.length == 0"><b>没有找到英雄!</b>

<div ng-repeat="h in hero | filter:{comic:'Marvel'}" ng-show="cbMarvel">{{ h.name}} - {{h.comic}}

<div ng-repeat="h in hero | filter:{comic:'DC'}" ng-show="cbDCComics">{{ h.name}} - {{h.comic}}

</fieldset></html>

解决方案

您可以在绑定数据时在视图模型本身中设置该计数,或者仅在作用域上设置一个返回计数的方法.

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

并将其用作:-

 奇迹 [{{getCount("Marvel")}}].....DC漫画[{{getCount("DC")}}]

Plnkr

如果您在页面上时列表没有变化,我建议找出长度并将其绑定到视图模型本身的属性,然后在视图中使用它.

//设置你的数据模型$scope.cbMarvel = {value:true, count:getCount('Marvel')};$scope.cbDCComics = {value:true, count:getCount('DC')};

在你看来

 奇迹 [{{cbMarvel.count}}]

Plnkr2

如果您的数据集很大,不要在 getCount 中使用过滤器,而是使用 forEach 并一次性填充每种类型的计数.

<小时>

事实上,您根本不需要过滤器,在您的情况下使用过滤器遍历同一个列表似乎效率低下.您的列表是静态列表,因此请在控制器本身中对其进行分类.

var 漫画 = $scope.comics = {};//漫画词典//在这里创建集合.angular.forEach(英雄,功能(itm){如果(!漫画[itm.comic]){漫画[itm.comic] = {name:itm.comic, value:true, count:1, items:[itm] };返回;}漫画[itm.comic].count++;//增量计数漫画[itm.comic].items.push(itm);//推送特定项目});

并删除视图中的所有过滤器,然后执行:-

 

{{ h.name}} - {{h.comic}}

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

Plnk3 - 更好的

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 have a plunker that does everything but count the subset here.

My Controller looks like this:

var app = angular.module('app', []);

app.controller('MainController', function($scope){
  $scope.cbMarvel = true;
  $scope.cbDCComics = true;

  $scope.heroes = [
    {
      id: 1,
      name: 'Iron Man',
      fname: 'Tony',
      lname: 'Stark',
      location: 'Stark Tower',
      comic: 'Marvel'
    },
    {
      id: 2,
      name: 'Batman',
      fname: 'Bruce',
      lname: 'Wayne',
      location: 'Bat Cave',
      comic: 'DC'
    },
    {
      id: 3,
      name: 'Superman',
      fname: 'Clark',
      lname: 'Kent',
      location: 'Metroplis',
      comic: 'DC'
    },
    {
      id: 1,
      name: 'Daredevil',
      fname: 'Jack',
      lname: 'Murdock',
      location: 'Court Room',
      comic: 'Marvel'
    },
    {
      id: 5,
      name: 'Flash',
      fname: 'Barry',
      lname: 'Allen',
      location: 'Speedline',
      comic: 'DC'
    },
    {
      id: 6,
      name: 'Hulk',
      fname: 'Bruce',
      lname: 'Banner',
      location: 'Labratory',
      comic: 'Marvel'
    },
    {
      id: 7,
      name: 'Hawkeye',
      fname: 'Clint',
      lname: 'Barton',
      location: 'Nest',
      comic: 'Marvel'
    },
    {
      id: 8,
      name: 'Thor',
      fname: 'Donald',
      lname: 'Blake',
      location: 'Asgard',
      comic: 'Marvel'
    }
  ];
});

And my view looks like this:

<!DOCTYPE html>
<html ng-app="app">
  <head>
    <link data-require="bootstrap@*" data-semver="3.2.0" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.css" />
    <link data-require="bootstrap-css@*" data-semver="3.2.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
    <script data-require="bootstrap@*" data-semver="3.2.0" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.js"></script>
    <script data-require="jquery@2.0.3 current" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
    <script data-require="angular.js@1.2.20" data-semver="1.2.20" src="https://code.angularjs.org/1.2.20/angular.js"></script>
    <script data-require="angular-ui-bootstrap@*" data-semver="0.11.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="MainController">
     <fieldset>
        <legend>Comments Log</legend>
        <div class="row">
            <div class="col-md-4">
                <input type="checkbox" ng-model="cbMarvel"/> Marvel [X]
            </div>
            <div class="col-md-4">&nbsp;</div>
            <div class="col-md-4">
                <input type="checkbox" ng-model="cbDCComics"/> DC Comics [X]
            </div>
        </div>

        <div class="row">&nbsp;</div>

        <div class="row col-md-10">
            <div ng-if="heroes.length == 0"><b>No Heroes Found!</b>
            </div>
            <div ng-repeat="h in heroes | filter:{comic:'Marvel'}" ng-show="cbMarvel">
                {{ h.name}} - {{h.comic}}
            </div>
            <div ng-repeat="h in heroes | filter:{comic:'DC'}" ng-show="cbDCComics">
              {{ h.name}} - {{h.comic}}
            </div>
        </div>
    </fieldset>
  </body>

</html>

解决方案

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

这篇关于AngularJS:计算过滤的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆