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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 05:37:43  来源:igfitidea点击:

Group item detail using AngularJs ng-repeat

javascriptangularjsangularjs-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 resolverfunction of lodash's memoize:

你可能需要用到resolverlodash 的 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 groupByfilter 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. Memoizationmeeans 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过滤器来动态修改视图中使用的数据。这是我想出的。这个过滤器每次都会返回一个新对象,这将导致无限的摘要循环,所以我将它包装在我的服务中,以修复这些类型的问题。这个只是由 修复memoizationMemoization意味着给定相同的参数(输入,道具),将从缓存中返回完全相同的输出,因此再次返回相同的对象,而不是创建一个看起来相同的新对象。此过滤器还支持嵌套的属性名称,因此您可以轻松地按嵌套在对象中的属性进行分组。

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 filterStabilizeservice should fix any filter, but any good memoizefunction 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>