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

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

问题描述

我显示列表的子集,如果一个复选框被选中。我想换成旁边的复选框以选择条件匹配的列表中的计数的X.我有一个plunker,做的一切,但算子 rel=\"nofollow\">。

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

  VAR应用= angular.module('应用',[]);app.controller('MainController',函数($范围){
  $ scope.cbMarvel =真;
  $ scope.cbDCComics = TRUE;  $ scope.heroes = [
    {
      ID:1,
      名称:钢铁侠,
      FNAME:'托尼',
      LNAME:斯塔克,
      位置:斯塔克大厦,
      漫画:奇迹
    },
    {
      ID:2,
      名称:'蝙蝠侠',
      FNAME:'布鲁斯,
      LNAME:'韦恩',
      位置:蝙蝠洞,
      漫画:DC
    },
    {
      ID:3,
      名称:'超人',
      FNAME:'克拉克',
      LNAME:肯特,
      位置:Metroplis',
      漫画:DC
    },
    {
      ID:1,
      名称:夜魔侠,
      FNAME:'杰克',
      LNAME:'默多克',
      位置:法院室,
      漫画:奇迹
    },
    {
      ID:5,
      名称:'闪光',
      FNAME:巴里,
      LNAME:艾伦,
      位置:Speed​​line公司',
      漫画:DC
    },
    {
      编号:6,
      名称:'绿巨人',
      FNAME:'布鲁斯,
      LNAME:'旗帜',
      位置:Labratory',
      漫画:奇迹
    },
    {
      ID:7,
      名称:'鹰眼',
      FNAME:克林特',
      LNAME:巴顿,
      位置:'鸟巢',
      漫画:奇迹
    },
    {
      ID:8,
      名称:'雷神',
      FNAME:唐纳德,
      LNAME:布雷克,
      位置:仙宫,
      漫画:奇迹
    }
  ];
});

和我的看法是这样的:

 <!DOCTYPE HTML>
< HTML NG-应用=应用程序>
  < HEAD>
    <链路数据需要=引导@ *数据semver =3.2.0的rel =stylesheet属性HREF =htt​​ps://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.css />
    <链路数据需要=引导,CSS @ *数据semver =3.2.0的rel =stylesheet属性HREF =// maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min的.css/>
    &所述;脚本数据需要=自举@ *数据semver =3.2.0SRC =htt​​ps://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.js>&下; / SCRIPT>
    &所述;脚本数据需要=jquery@2.0.3电流数据semver =2.0.3SRC =HTTP://$c$c.jquery.com/jquery-2.0.3.min.js >< / SCRIPT>
    &所述;脚本数据需要=angular.js@1.2.20数据semver =1.2.20SRC =的https://$c$c.angularjs.org/1.2.20/angular.js&GT ;< / SCRIPT>
    &所述;脚本数据需要=角的ui-引导@ *数据semver =0.11.0SRC =htt​​p://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11。 0.min.js>< / SCRIPT>
    <链接rel =stylesheet属性HREF =style.css文件/>
    &所述; SCRIPT SRC =的script.js>&下; /脚本>
  < /头>  <机身NG控制器=MainController>
     <&字段集GT;
        <传奇>评论日志< /传说>
        < D​​IV CLASS =行>
            < D​​IV CLASS =COL-MD-4>
                <输入类型=复选框NG模型=cbMarvel/>奇迹[X]
            < / DIV>
            < D​​IV CLASS =COL-MD-4>&安培; NBSP;< / DIV>
            < D​​IV CLASS =COL-MD-4>
                <输入类型=复选框NG模型=cbDCComics/> DC漫画[X]
            < / DIV>
        < / DIV>        < D​​IV CLASS =行>&安培; NBSP;< / DIV>        < D​​IV CLASS =行COL-MD-10>
            < D​​IV NG-IF =heroes.length == 0>< B>没有英雄找到<!/ B>
            < / DIV>
            < D​​IV NG重复=英雄中的H |过滤器:{漫画:'奇迹'}NG秀=cbMarvel>
                {{h.name}} - {{h.comic}}
            < / DIV>
            < D​​IV NG重复=英雄中的H |过滤器:{漫画:DC}NG秀=cbDCComics>
              {{h.name}} - {{h.comic}}
            < / DIV>
        < / DIV>
    < /字段集>
  < /身体GT;< / HTML>


您可以设置在视图模型本身的数量,同时结合数据,或者只是在返回的计数范围的方法。

  app.controller('MainController',函数($范围,filterFilter){
   ....
    $ scope.getCount =函数(strcat的){
      返回filterFilter($ scope.heroes,{漫画:strcat的})长;
    }
    ...
});

和使用它作为: -

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

Plnkr

如果该列表是不变化的,当你的页面,我建议找出长度并将其绑定到视图模型本身的属性,并在视图中使用它。

  //设置你的数据模型
  $ scope.cbMarvel = {值:真,计数:getCount将('奇迹')};
  $ scope.cbDCComics = {值:真,计数:getCount将(DC)};

和在你看来

 <输入类型=复选框NG模型=cbMarvel.value/>奇迹[{{cbMarvel.count}}]

Plnkr2

如果您的数据集是巨大的,而不是使用getCount将过滤器内,使用foreach并立即填充每种类型的计数。


逸岸你并不需要一个过滤器的话,那似乎是低效的使用,通过在你的情况下,过滤器相同的列表进行迭代。你的是一个静态列表控制器本身,以便对其进行分类。

  VAR漫画= $ scope.comics = {}; //漫画词典
  //这里创建集合。
  angular.forEach(英雄,功能(ITM){
    如果(!漫画[itm.comic]){
     漫画[itm.comic] = {名称:itm.comic,值:真,数:1,项目:[ITM]};
     返回;
    }    漫画[itm.comic] .Count之间++; //增量计数
    漫画[itm.comic] .items.push(ITM); //推动特定项目
  });

和删除所有过滤器在您看来,做: -

 < D​​IV NG重复=H在comics.Marvel.itemsNG秀=comics.Marvel.value>
        {{h.name}} - {{h.comic}}
    < / DIV>
    < D​​IV NG重复=H在comics.DC.itemsNG秀=comics.DC.value>
      {{h.name}} - {{h.comic}}
    < / DIV>

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天全站免登陆