Group item detail using AngularJs ng-repeat

时间秒杀一切 提交于 2019-11-30 20:08:37

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 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:

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.

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).

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>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!