Jak grupować dane za pomocą filtra kątowego?
Mam listę graczy, którzy należą do grupy każdy. Jak mogę użyć filtra, aby wyświetlić listę Użytkowników według grupy?
[{name: 'Gene', team: 'team alpha'},
{name: 'George', team: 'team beta'},
{name: 'Steve', team: 'team gamma'},
{name: 'Paula', team: 'team beta'},
{name: 'Scruath of the 5th sector', team: 'team gamma'}];
Szukam tego wyniku:
- team alpha
- Gen
- team beta
- George
- Paula
- Team gamma
- Steve
- Scruath piątego SEKTORA
7 answers
Możesz użyć groupBy of angular.filtr Moduł.
więc możesz zrobić coś takiego:
JS:
$scope.players = [
{name: 'Gene', team: 'alpha'},
{name: 'George', team: 'beta'},
{name: 'Steve', team: 'gamma'},
{name: 'Paula', team: 'beta'},
{name: 'Scruath', team: 'gamma'}
];
HTML:
<ul ng-repeat="(key, value) in players | groupBy: 'team'">
Group name: {{ key }}
<li ng-repeat="player in value">
player: {{ player.name }}
</li>
</ul>
Wynik:
Nazwa grupy: alpha
* gracz: Gene
Nazwa grupy: beta
* gracz: George
* gracz: Paula
Nazwa grupy: gamma
* gracz: Steve
* gracz: Scruath
Aktualizacja: Jsbin Zapamiętaj podstawowe wymagania, aby używać angular.filter
, szczególnie zauważ, że musisz dodać go do zależności twojego modułu:
(1) możesz zainstalować angular-filter używając 4 różnych metod:
Klonuj i buduj to repozytorium]} Dzięki temu, że Użytkownik nie ma dostępu do plików cookie, nie ma dostępu do plików cookie.]}
- poprzez npm: uruchamiając $ npm install angular-filter z terminala
- przez cdnjs http://www.cdnjs.com/libraries/angular-filter
(2) Include filtr kątowy.js (lub angular-filter./ min.js) w indeksie.html, po włączeniu samego Angular.
(3) Dodaj 'angular.filter 'to your main module' s list of dependencies.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-28 19:25:05
Oprócz zaakceptowanych odpowiedzi powyżej stworzyłem ogólny filtr 'groupBy' za pomocą podkreślenia.biblioteka js.
JSFiddle (aktualizacja): http://jsfiddle.net/TD7t3/
Filtr
app.filter('groupBy', function() {
return _.memoize(function(items, field) {
return _.groupBy(items, field);
}
);
});
Zwróć uwagę na wezwanie "memoize". Ta metoda podkreśla buforuje wynik funkcji i zatrzymuje angular od oceny wyrażenia filtra za każdym razem, zapobiegając w ten sposób kątowi przed osiągnięciem limitu iteracji digest.
Na html
<ul>
<li ng-repeat="(team, players) in teamPlayers | groupBy:'team'">
{{team}}
<ul>
<li ng-repeat="player in players">
{{player.name}}
</li>
</ul>
</li>
</ul>
Stosujemy nasz filtr 'groupBy' na zmiennej teamplayers scope, na właściwości 'team'. Nasz ng-repeat otrzymuje kombinację (key, values []), którą możemy wykorzystać w kolejnych iteracjach.
Aktualizacja 11 czerwca 2014 Rozszerzyłem grupę o filtr, aby uwzględnić użycie wyrażeń jako klucza (np. zagnieżdżone zmienne). Usługa angular parse przydaje się do tego:
Filtr (z wyrażeniem wsparcie)
app.filter('groupBy', function($parse) {
return _.memoize(function(items, field) {
var getter = $parse(field);
return _.groupBy(items, function(item) {
return getter(item);
});
});
});
Kontroler (z zagnieżdżonymi obiektami)
app.controller('homeCtrl', function($scope) {
var teamAlpha = {name: 'team alpha'};
var teamBeta = {name: 'team beta'};
var teamGamma = {name: 'team gamma'};
$scope.teamPlayers = [{name: 'Gene', team: teamAlpha},
{name: 'George', team: teamBeta},
{name: 'Steve', team: teamGamma},
{name: 'Paula', team: teamBeta},
{name: 'Scruath of the 5th sector', team: teamGamma}];
});
Html (z wyrażeniem sortBy)
<li ng-repeat="(team, players) in teamPlayers | groupBy:'team.name'">
{{team}}
<ul>
<li ng-repeat="player in players">
{{player.name}}
</li>
</ul>
</li>
JSFiddle: http://jsfiddle.net/k7fgB/2/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-11 06:24:15
Najpierw wykonaj pętlę używając filtru, który zwróci tylko unikalne drużyny, a następnie zagnieżdżoną pętlę, która zwróci wszystkich graczy z bieżącej drużyny:
Http://jsfiddle.net/plantface/L6cQN/
Html:
<div ng-app ng-controller="Main">
<div ng-repeat="playerPerTeam in playersToFilter() | filter:filterTeams">
<b>{{playerPerTeam.team}}</b>
<li ng-repeat="player in players | filter:{team: playerPerTeam.team}">{{player.name}}</li>
</div>
</div>
Skrypt:
function Main($scope) {
$scope.players = [{name: 'Gene', team: 'team alpha'},
{name: 'George', team: 'team beta'},
{name: 'Steve', team: 'team gamma'},
{name: 'Paula', team: 'team beta'},
{name: 'Scruath of the 5th sector', team: 'team gamma'}];
var indexedTeams = [];
// this will reset the list of indexed teams each time the list is rendered again
$scope.playersToFilter = function() {
indexedTeams = [];
return $scope.players;
}
$scope.filterTeams = function(player) {
var teamIsNew = indexedTeams.indexOf(player.team) == -1;
if (teamIsNew) {
indexedTeams.push(player.team);
}
return teamIsNew;
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-10 18:06:08
Oryginalnie użyłem odpowiedzi Plantface, ale nie podobało mi się, jak wygląda składnia moim zdaniem.
Przerobiłem go, aby użyć $q.defer, aby przetworzyć Dane i zwrócić listę unikalnych zespołów, która jest następnie używana jako filtr.
Http://plnkr.co/edit/waWv1donzEMdsNMlMHBa?p=preview
Widok
<ul>
<li ng-repeat="team in teams">{{team}}
<ul>
<li ng-repeat="player in players | filter: {team: team}">{{player.name}}</li>
</ul>
</li>
</ul>
Controller
app.controller('MainCtrl', function($scope, $q) {
$scope.players = []; // omitted from SO for brevity
// create a deferred object to be resolved later
var teamsDeferred = $q.defer();
// return a promise. The promise says, "I promise that I'll give you your
// data as soon as I have it (which is when I am resolved)".
$scope.teams = teamsDeferred.promise;
// create a list of unique teams. unique() definition omitted from SO for brevity
var uniqueTeams = unique($scope.players, 'team');
// resolve the deferred object with the unique teams
// this will trigger an update on the view
teamsDeferred.resolve(uniqueTeams);
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-07 16:05:13
Obie odpowiedzi były dobre, więc przeniosłem je do dyrektywy, aby mogła być wielokrotnego użytku, a druga zmienna zakresu nie musiała być definiowana.
Oto fiddle Jeśli chcesz zobaczyć to zaimplementowane
Poniżej znajduje się dyrektywa:
var uniqueItems = function (data, key) {
var result = [];
for (var i = 0; i < data.length; i++) {
var value = data[i][key];
if (result.indexOf(value) == -1) {
result.push(value);
}
}
return result;
};
myApp.filter('groupBy',
function () {
return function (collection, key) {
if (collection === null) return;
return uniqueItems(collection, key);
};
});
Następnie można go użyć w następujący sposób:
<div ng-repeat="team in players|groupBy:'team'">
<b>{{team}}</b>
<li ng-repeat="player in players | filter: {team: team}">{{player.name}}</li>
</div>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-30 09:39:56
Update
Początkowo napisałem tę odpowiedź, ponieważ stara wersja rozwiązania zaproponowanego przez Ariel M. w połączeniu z innymi $filter
s wywołała "Błąd pętli Infite $diggest" (infdig
). Na szczęście ten problem został rozwiązany w najnowszej wersji angular.filtr .
Zaproponowałem następującą implementację, która nie miała tego problemu :
angular.module("sbrpr.filters", [])
.filter('groupBy', function () {
var results={};
return function (data, key) {
if (!(data && key)) return;
var result;
if(!this.$id){
result={};
}else{
var scopeId = this.$id;
if(!results[scopeId]){
results[scopeId]={};
this.$on("$destroy", function() {
delete results[scopeId];
});
}
result = results[scopeId];
}
for(var groupKey in result)
result[groupKey].splice(0,result[groupKey].length);
for (var i=0; i<data.length; i++) {
if (!result[data[i][key]])
result[data[i][key]]=[];
result[data[i][key]].push(data[i]);
}
var keys = Object.keys(result);
for(var k=0; k<keys.length; k++){
if(result[keys[k]].length===0)
delete result[keys[k]];
}
return result;
};
});
Jednak ta implementacja będzie działać tylko z wersjami przed Angular 1.3. (Wkrótce zaktualizuję tę odpowiedź, dostarczając rozwiązanie, które działa ze wszystkimi wersjami.)
Napisałem post o krokach, które podjąłem, aby rozwinąć to $filter
, problemach, które napotkałem i rzeczach, których się z tego nauczyłem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-20 03:05:51
Oprócz zaakceptowanej odpowiedzi możesz użyć tego, jeśli chcesz pogrupować według wiele kolumn :
<ul ng-repeat="(key, value) in players | groupBy: '[team,name]'">
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-10 19:34:36