javascript 使用 AngularJs ng-repeat 对项目详细信息进行分组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26186514/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Group item detail using AngularJs ng-repeat
提问by Greg Grater
I would like to perform a group by function inside of an ng-repeat
我想在 ng-repeat 中按功能执行分组
Given the following data:
鉴于以下数据:
var items = [];
items.push({ id: 1, widgetId: 54, colorId: 45 });
items.push({ id: 2, widgetId: 54, colorId: 72 });
items.push({ id: 3, widgetId: 54, colorId: 29 });
items.push({ id: 4, widgetId: 55, colorId: 67 });
items.push({ id: 5, widgetId: 55, colorId: 29 });
items.push({ id: 6, widgetId: 56, colorId: 29 });
items.push({ id: 7, widgetId: 56, colorId: 72 });
items.push({ id: 8, widgetId: 57, colorId: 75 });
I would like an ng-repeat that results in the following presentation
我想要一个 ng-repeat 导致以下演示
widgetId 54 colorId: 45 colorId: 72 colorId 29
widgetId 55 colorId: 67 colorId: 29
widgetId 56 colorId: 29 colorId: 72
widgetId 57 colorId: 75
...and markup
...和标记
<div class="container">
<div class="row">
<div>widgetId: 54</div>
<div>
<div>colorId: 45</div>
<div>colorId: 72</div>
<div>colorId: 29</div>
</div>
</div>
<div class="row">
<div>widgetId: 55</div>
<div>
<div>colorId: 67</div>
<div>colorId: 29</div>
</div>
</div>
<div class="row">
<div>widgetId: 56</div>
<div>
<div>colorId: 29</div>
<div>colorId: 72</div>
</div>
</div>
<div class="row">
<div>widgetId: 57</div>
<div>
<div>colorId: 75</div>
</div>
</div>
</div>
Any suggestions that don't include creating separate arrays? The data is coming to me this way and it would be nice to avoid manipulating it.
任何不包括创建单独数组的建议?数据以这种方式传给我,避免操纵它会很好。
回答by m59
Update - the simple, clean way:
更新 - 简单、干净的方式:
Use npm modules! Lodash can handle the groupBy and the memoization needed to avoid an infinite loop as an Angular filter.
使用 npm 模块!Lodash 可以处理 groupBy 和避免无限循环所需的记忆作为 Angular 过滤器。
npm install lodash
var memoize = require('lodash/function/memoize');
var groupBy = require('lodash/collection/groupBy');
app.filter('groupBy', function() {
return memoize(groupBy);
});
You may need to use the resolver
function of lodash's memoize:
你可能需要用到resolver
lodash 的 memoize 功能:
app.filter('groupBy', function() {
return memoize(function() {
return groupBy.apply(null, arguments);
}, function() {
return JSON.stringify([].slice.call(arguments));
});
});
But, I really believe you should just simplify all of this and filter in the controller:
但是,我真的相信您应该简化所有这些并在控制器中进行过滤:
$scope.foo = function() { // run this when user clicked button, etc
$scope.groupedItems = groupBy($scope.items, 'stuff');
};
Old Answer:
旧答案:
I suggest a groupBy
filter to modify the data used in the view on the fly. Here's what I came up with. This filter returns a new object each time which will cause an infinite digest cycle, so I wrapped it in my service that fixes those kinds of problems. This one is simply fixed by memoization
. Memoization
meeans that given the same parameters (input, prop), the exact same output will be returned from a cache, so the same object is returned again, rather than creating a new one that looks the same. This filter also supports nested property names, so you can easily group by a property nested within the objects.
我建议使用groupBy
过滤器来动态修改视图中使用的数据。这是我想出的。这个过滤器每次都会返回一个新对象,这将导致无限的摘要循环,所以我将它包装在我的服务中,以修复这些类型的问题。这个只是由 修复memoization
。Memoization
意味着给定相同的参数(输入,道具),将从缓存中返回完全相同的输出,因此再次返回相同的对象,而不是创建一个看起来相同的新对象。此过滤器还支持嵌套的属性名称,因此您可以轻松地按嵌套在对象中的属性进行分组。
Live Demo
现场演示
<div class="container">
<div class="row" ng-repeat="(setKey, set) in items | groupBy:'widgetId'">
WidgetId: {{setKey}}
<div ng-repeat="item in set">
ColorId: {{item.colorId}}
</div>
</div>
</div>
The filter:
过滤器:
.filter('groupBy', [
'$parse',
'pmkr.filterStabilize',
function($parse, filterStabilize) {
function groupBy(input, prop) {
if (!input) { return; }
var grouped = {};
input.forEach(function(item) {
var key = $parse(prop)(item);
grouped[key] = grouped[key] || [];
grouped[key].push(item);
});
return grouped;
}
return filterStabilize(groupBy);
}])
My filterStabilize
service should fix any filter, but any good memoize
function will do fine in this case (and most cases).
我的filterStabilize
服务应该修复任何过滤器,但memoize
在这种情况下(和大多数情况下),任何好的功能都可以正常工作。
回答by slotomo
Try like this:
像这样尝试:
<div class="container">
<div class="row" ng-repeat="(key, value) in items| groupBy: 'widgetId'">
<div>widgetId: {{ key }}</div>
<div>
<div ng-repeat="color in value">
colorId: {{color.colorId}}
</div>
</div>
</div>
</div>