javascript - 使用 AngularJs ng-repeat 对项目详细信息进行分组

标签 javascript angularjs angularjs-ng-repeat

我想在 ng-repeat 中按函数执行分组

给定以下数据:

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 });

我想要一个 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

...和标记

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

有没有不包括创建单独数组的建议?数据以这种方式传给我,最好避免操纵它。

最佳答案

更新 - 简单、干净的方式:

使用 npm 模块! Lodash 可以像 Angular 过滤器一样处理 groupBy 和避免无限循环所需的内存。

npm install lodash
var memoize = require('lodash/function/memoize');
var groupBy = require('lodash/collection/groupBy');
app.filter('groupBy', function() {
  return memoize(groupBy);
});

你可能需要用到lodash的memoize的resolver功能:

app.filter('groupBy', function() {
  return memoize(function() {
    return groupBy.apply(null, arguments);
  }, function() {
    return JSON.stringify([].slice.call(arguments));
  });
});

但是,我真的相信你应该简化所有这些并在 Controller 中进行过滤:

$scope.foo = function() { // run this when user clicked button, etc
  $scope.groupedItems = groupBy($scope.items, 'stuff');
};

旧答案:

我建议使用 groupBy 过滤器来动态修改 View 中使用的数据。这是我想出的。这个过滤器每次都会返回一个新对象,这将导致无限的摘要循环,所以我将它包装在我的服务中以修复这些类型的问题。这一个简单地通过memoization 修复。 Memoization 意味着给定相同的参数(输入、prop),完全相同的输出将从缓存返回,因此再次返回相同的对象,而不是创建一个看起来相同的新对象。此过滤器还支持嵌套的属性名称,因此您可以轻松地按嵌套在对象中的属性进行分组。

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>

过滤器:

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

 }])

我的 filterStabilize服务应该修复任何过滤器,但任何好的 memoize 函数在这种情况下(和大多数情况下)都可以正常工作。

关于javascript - 使用 AngularJs ng-repeat 对项目详细信息进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26186514/

相关文章:

javascript - 如何根据对象的id获取数据

javascript - base64的前缀 'data:image/png;base64,'对显示图像有影响吗?

javascript - AngularJS/Jade 错误 : Argument 'MyController' is not a function, 未定义(平均值)

javascript - Angularjs ng 重复 - 按 $index 删除

javascript - ng-repeat 内的 ng-repeat 创建空的 td 元素 - Angular

javascript - 在 couchdb reduce 中使用 "eval"- 这有多危险?

javascript - 如何将排序和匹配谷歌表格公式转换为应用程序脚本/javascript?

javascript - AngularJS $http.put PUT 方法不发送数据

javascript - Angularjs - json内容不显示

javascript - 是否可以定义中缀函数?