Je montre des sous-ensembles d'une liste si une case est cochée. Je voudrais remplacer le X à côté de la case à cocher par le nombre de la liste correspondant aux critères de sélection. J'ai un plongeur qui fait tout mais compte le sous-ensemble ici .
Mon contrôleur ressemble à ceci:
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'
}
];
});
Et ma vue ressemble à ceci:
<!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="[email protected] current" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script data-require="[email protected]" 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"> </div>
<div class="col-md-4">
<input type="checkbox" ng-model="cbDCComics"/> DC Comics [X]
</div>
</div>
<div class="row"> </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>
Vous pouvez définir ce nombre dans le modèle de vue lui-même lors de la liaison des données ou simplement avoir une méthode sur la portée qui renvoie le nombre.
app.controller('MainController', function($scope, filterFilter){
....
$scope.getCount = function(strCat){
return filterFilter( $scope.heroes, {comic:strCat}).length;
}
...
});
et l'utiliser comme: -
Marvel [{{getCount("Marvel")}}]
.....
DC Comics [{{getCount("DC")}}]
Si la liste ne change pas lorsque vous êtes sur la page, je suggère de découvrir la longueur et de la lier à une propriété dans le modèle de vue lui-même, et de l'utiliser dans la vue.
//Set your data model
$scope.cbMarvel = {value:true, count:getCount('Marvel')};
$scope.cbDCComics = {value:true, count:getCount('DC')};
et à votre avis
<input type="checkbox" ng-model="cbMarvel.value"/> Marvel [{{cbMarvel.count}}]
Si votre jeu de données est énorme, au lieu d'utiliser un filtre à l'intérieur du getCount, utilisez un forEach et remplissez le nombre pour chaque type à la fois.
En fait, vous n'avez pas du tout besoin d'un filtre, il semble inefficace de parcourir la même liste en utilisant un filtre dans votre cas. La vôtre est une liste statique, alors catégorisez-la dans le contrôleur lui-même.
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
});
et supprimez tous les filtres dans votre vue et faites: -
<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>
En supposant que votre liste de personnes est dans une variable de données et que vous filtrez les personnes à l'aide du modèle de requête, le code suivant fonctionnera pour vous:
{{(data|filter:query).length}}
{{data.length}}
résumé
{{data.length}}
- imprime le nombre total de personnes
{{(data|filter:query).length}}
- imprime le nombre filtré de personnes
Vous pouvez en fait enregistrer une référence aux résultats filtrés dans une variable: h in filtered.marvel = (heroes | filter:{comic:'Marvel'})
, que vous pouvez utiliser comme ceci: filtered.marvel.length
.
Voir: Plunkr
Vous pouvez également déplacer ce code vers votre contrôleur:
$scope.filteredHeroes.marvel = $filter('filter')($scope.heroes, {comic:'Marvel'});
, que vous pourriez utiliser par ng-repeat="hero in filteredHeroes.marvel"
et {{filteredHeroes.marvel.length}}
(N'oubliez pas d'ajouter $ filter comme dépendance du contrôleur)
Voir: Plunkr
Pour trouver les objets de comptage, j'utilise <scope_obj>.length
dans le .html
modèle.
Voici mon contrôleur:
conciergeControllers.controller('GuestMsgPreviewCtrl', ['$scope', 'GuestMessages',
function($scope, GuestMessages) {
$scope.guests = GuestMessages.query();
}]);
Et le modèle (chaque objet invité a un attribut messages qui est un objet tableau, donc .length
renvoie le nombre d'objets message
imbriqués:
<ul ng-repeat="guest in guests">
<li>[[ guest.messages.length ]]</li>
</ul>