【问题标题】:Skip duplicated items while ng-repeatng-repeat 时跳过重复的项目
【发布时间】:2019-08-17 15:15:52
【问题描述】:

有一个嵌套数组,由捆绑包组成,这些捆绑包又包含项目。所以,我想在迭代时根据以前的捆绑项目跳过下一个捆绑的相同项目。下面是数据模型和代码sn-ps:

vm.data

[
  {
    id: '01',
    name: 'Dummy1',
    items: [{
      id: 'itemOne',
      name: 'ItemOne',
      desc: 'ItemOne description'
    }]
  },
  {
    id: '02',
    name: 'Dummy2',
    items: [{
      id: 'itemOne',
      name: 'ItemOne',
      desc: 'ItemOne description'
    },
    {
      id: 'otherItem',
      name: 'OtherItem',
      desc: 'OtherItem description'
    }]
  },
  ...
]

HTML:

<div ng-repeat="bundle in vm.data track by $index">
  ...
  <ul>
    <li ng-repeat="item in bundle.items" ng-if="vm.check(item, $parent.$index)">
      <span ng-bind="item.name"></span>
      ...
    </li>
  </ul>
</div>

vm.check:

vm.check = function(item, bundleIdx) {
  if (bundleIdx > 0) {
    return _.some(vm.data[bundleIdx-1].items, function(obj) {
      return obj.id !== item.id;
    });
  } else {
    // first bundle, so show all items
    return true;
  }
};

演示是here

它部分工作,即第二个包正确匹配条件,但第三个包不匹配。那么,我错过了什么?任何帮助将不胜感激!

【问题讨论】:

  • 为什么不在使用 ng-repeat 之前简单地构建一组独特的项目呢?它将简化您的模板并将复杂的逻辑移动到它所属的位置,在 javascript 中。

标签: arrays multidimensional-array angularjs-ng-repeat angularjs-ng-if


【解决方案1】:

我会将复杂的逻辑排除在您的模板之外。相反,您应该在尝试使用 vm.data 之前对其进行转换。

var items = {};
vm.bundles = [];
vm.data.forEach(function(data) {

    var bundle = {
        id: data.id,
        name: data.name,
        items: []
    };

    data.items.forEach(function(item) {
        if (!items[item.id]) {
            bundle.items.push(item);
        }
        items[item.id] = true;
    });

    vm.bundles.push(bundle);
});

然后您的模板可以简单地使用转换后的数据。

<div ng-repeat="bundle in vm.bundles track by $index">
    ...
    <ul>
        <li ng-repeat="item in bundle.items">
            <span>{{item.name}}</span>
            ...
        </li>
    </ul>
</div>

【讨论】:

  • 感谢您的回答。您提出的解决方案对于小型数据结构很方便...我在问题中提到的 vm.data (数据结构)实际上在每个对象的字段方面相当大,所以我简化了它...并使用您的解决方案来解决这些问题(巨大的)数据对我来说将是高图表(在 js 端复制数据字段)。但我给你ThumbsUp
  • 如果您必须在 HTML 中执行此操作,您可以使用过滤器而不是 ng-if 指令(例如 ng-repeat="item in bundle.items | filterItems"),这可能更适合您的用例。但是您的 vm.check 方法仍然不会非常高效,因为它会遍历每个项目的所有先前项目,您可能希望以某种方式优化它(就像在我的回答中一样)。非常大的数据集对 DOM 不友好,如果您在网页中呈现大量数据,无论哪种方法都会遇到性能问题。
猜你喜欢
  • 2015-09-13
  • 2018-07-22
  • 2013-12-30
  • 2013-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-11
  • 2018-08-21
相关资源
最近更新 更多