Ng-重复ng-显示前一项目字段值是否不同

时间:2013-07-16 03:39:01

标签: angularjs angularjs-ng-repeat

如果包含按日期排序的日期字段的项目列表。我想按日期分类这些项目,如;

日期1

  • ITEM1

日期2

  • ITEM2
  • 项目3

依此类推......

我拥有的是这个;

<ul>
    <li ng-repeat="listing in listings | filter:query">
        <h1 ng-show="$index === 0 || listings[$index - 1].created !== listing.created">
            {{listing.created | date:mediumDate}}
        </h1>
        {{listing.title}}
    </li>
</ul>

但是这种方式h1元素成为了弄乱演示的li元素的孩子。有没有其他方法以我想要的方式写这个ng-repeat?

2 个答案:

答案 0 :(得分:3)

我的解决方案可能无效,具体取决于列表中的项目数。

我的想法是应用过滤器将简单列表转换为分层列表。

这里是working jsFiddle(看到底部的新版,真的!)

这个想法很简单,拿一个现有的列表,并在运行中重新排列:

<div ng-repeat="g in items | groupBy:'group' | orderBy:'group'">
    <h2>{{g.group}}</h2>
    <ul>
        <li ng-repeat="item in g.items | orderBy:'title'">{{item.id}}. {{item.title}}</li>
    </ul>
</div>

在这种情况下,我们会使用原始数组,并对其应用groupBy过滤器。这个过滤器实际上有点复杂,因为它需要确保它不会超过必要的数量修改数组,因此它必须存储原始数组的深层副本以进行比较。如果删除深层复制和检查,每次最终都会出现$digest次迭代错误。

  

编辑:查看底部,了解执行数组较浅副本的修改版本

以下是过滤器代码:

app.filter("groupBy", function() {
    var mArr = null,
        mGroupBy = null,
        mRetArr = null;
    return function(arr, groupBy) {
        if(!angular.equals(mArr, arr) || mGroupBy !== groupBy) {
            mArr = angular.copy(arr);
            mGroupBy = groupBy;
            mRetArr = [];
            var groups = {};
            angular.forEach(arr, function(item) {
                var groupValue = item[groupBy]
                if(groups[groupValue]) {
                    groups[groupValue].items.push(item);
                } else {
                    groups[groupValue] = {
                        items: [item]
                    };
                    groups[groupValue][groupBy] = groupValue;
                    mRetArr.push(groups[groupValue]);
                }
            });
        }
        return mRetArr;
    };
});

mArrmGroupBymRetArr是&#34;记忆的&#34;值,在这里。)

这个过滤器有什么好处,它不会要求数据已经分组。上面链接的jsFiddle包含一个按钮,用于在最后动态地将项目添加到数组中,但它们最终仍然按组分组。

同样,真正需要注意的是,根据列表中的项目数量,它可能会很慢和/或很昂贵。数百个中等复杂的项目应该没问题,但如果你有数千个,你应该在它们到达范围之前在其他地方对它们进行预先排序。


编辑:更好的版本

以更多代码复杂性为代价,我修改了过滤器以仅复制关键信息,而不是深度复制整个数组。这一次,我制作了包含这些项目的组的哈希映射。这些项目仍然被引用,但这次它是一个明确的引用,因此修改树中的项目不会强制求助,而是更改项目组或添加或删除项目。

新小提琴:http://jsfiddle.net/hhWaX/2/

这是新过滤器:

app.filter("groupBy", function() {
    var mArr = null,
        mGroupBy = null,
        mRetArr = null,
        getMemoArr = function(arr, groupBy) {
            var ret = {};
            angular.forEach(arr, function(item){
                var groupValue = item[groupBy];
                if(ret[groupValue]) {
                    ret[groupValue].push(item);
                } else {
                    ret[groupValue] = [item];
                }
            });
            return ret;
        };
    return function(arr, groupBy) {
        var newMemoArr = getMemoArr(arr, groupBy);
        if(mGroupBy !== groupBy || !angular.equals(mArr, newMemoArr)) {
            mArr = newMemoArr;
            mGroupBy = groupBy;
            mRetArr = [];
            var groups = {};
            angular.forEach(arr, function(item) {
                var groupValue = item[groupBy]
                if(groups[groupValue]) {
                    groups[groupValue].items.push(item);
                } else {
                    groups[groupValue] = {
                        items: [item]
                    };
                    groups[groupValue][groupBy] = groupValue;
                    mRetArr.push(groups[groupValue]);
                }
            });
        }
        return mRetArr;
    };
});

它要复杂得多,但是这个应该比大型集合具有明显更好的性能,因为原始数组的复制绝对最少。

答案 1 :(得分:1)

O(log n)

完美适合我。像这样

<li class="divider" ng-if="FormsList[$index].FORM_GROUP!=FormsList[$index-1].FORM_GROUP">