当新项目添加到模型时,对所有项目进行ng-repeat更改排序顺序 [英] ng-repeat changing sort order on all items when new item added to model

查看:90
本文介绍了当新项目添加到模型时,对所有项目进行ng-repeat更改排序顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个镶嵌"指令,该指令可让您包装多个div.

I created a "tessellate" directive that lets you wrap a number of divs.

<tessellate columns="4">
  <div class="thumbnail" ng-repeat="item in items track by item.id">
      {{item.Name}}<br />
      {{item.Summary}}
  </div>
</tessellate>

一次需要一个div,然后将其附加到指定列数中最短的一个,以创建镶嵌/镶嵌效果.

It takes one div at a time and appends it to the shortest of the specified number of columns to create a tessellation/mosaic effect.

在此处查看plunkr: http://plnkr.co/edit/ur0bVCFRSz1UbRHeLjz8?p=preview

See the plunkr here: http://plnkr.co/edit/ur0bVCFRSz1UbRHeLjz8?p=preview

问题在于,当模型更改时,ng-repeat使用div在DOM中出现的顺序 而不是模型中重绘元素的顺序.您可以看到这些项目最初是正确排序的,单击Add后,它将对第一列中的项目进行水平排序,然后对下一列中的项目进行排序,等等.

The problem is that when the model changes, the ng-repeat uses the order that the divs appear in the DOM instead of the order in the model to redraw the elements. You can see that the items are sorted correctly at first and after clicking Add it is sorting the items from the first column horizontally, then the ones from the next column, etc.

如何防止ng-repeat使用DOM命令重绘元素?我已经尝试添加orderBy item.id,但这没有帮助.

How can I keep ng-repeat from using the DOM order to redraw elements? I already tried adding orderBy item.id, but it didn't help.

var app = angular.module('app', []);

app.controller('itemController', ['$scope', function ($scope) {
    $scope.items = [
             { id:"1", Name:"Item1", Summary:"This is the summary of Item1" },
             { id:"2", Name:"Item2", Summary:"This is the summary of Item2. Some extra text on item two to test different heights." },
             { id:"3", Name:"Item3", Summary:"This is the summary of Item3" },
             { id:"4", Name:"Item4", Summary:"This is the summary of Item4. Some extra text on item four to test different heights." },
             { id:"5", Name:"Item5", Summary:"This is the summary of Item5. Some extra text on item five to test different heights. Some extra text on item to test different heights." },
             { id:"6", Name:"Item6", Summary:"This is the summary of Item6" },
             { id:"7", Name:"Item7", Summary:"This is the summary of Item7. Some extra text on item seven to test different heights." },
             { id:"8", Name:"Item8", Summary:"This is the summary of Item8" },
             { id:"9", Name:"Item9", Summary:"This is the summary of Item9. Some extra text on item nine to test different heights." },
             { id:"10", Name:"Item10", Summary:"This is the summary of Item10. Some extra text on item ten to test different heights." },
             { id:"11", Name:"Item11", Summary:"This is the summary of Item11" },
             { id:"12", Name:"Item12", Summary:"This is the summary of Item12. Some extra text on item to test different heights." },
             { id:"13", Name:"Item13", Summary:"This is the summary of Item13" },
             { id:"14", Name:"Item14", Summary:"This is the summary of Item14. Some extra text on item to test different heights." },
             { id:"15", Name:"Item15", Summary:"This is the summary of Item15. Some extra text on item to test different heights. Some extra text on item to test different heights." },
             { id:"16", Name:"Item16", Summary:"This is the summary of Item16" },
             { id:"17", Name:"Item17", Summary:"This is the summary of Item17. Some extra text on item to test different heights." },
             { id:"18", Name:"Item18", Summary:"This is the summary of Item18" }
             ];
    $scope.inc = $scope.items.length;
    $scope.add = function() {
        $scope.inc = $scope.inc + 1;
        $scope.items.push({ id: $scope.inc, Name: "New Item" + $scope.inc, Summary:"New Summary" });
    };
}]);

app.directive('tessellate', [function () {
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        scope: {
            columns: '='
        },
        controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
            $scope.numberToArray = function (num) {
                return new Array(num);
            };
        }],
        link: function (scope, elem, attrs, ctrl) {

            scope.$watch(function () {
                return elem.children().first().height();
            }, function (height) {
                if (height > 0) {
                    var containers = elem.children();
                    var transcludedDivsContainer = containers.first();
                    var targetColumns = containers.eq(1).children();

                    // Add the transcluded divs one at a time into the shortest column.
                    angular.forEach(transcludedDivsContainer.children(), function (div) {
                        var shortCol = null;
                        angular.forEach(targetColumns, function (col) {
                            col = angular.element(col);
                            if (shortCol === null || col.height() < shortCol.height()) {
                                shortCol = col;
                            }
                        });
                        shortCol.append(div);
                    });
                }
            }
            );
        },
        templateUrl: "tessellateTemplate.html"
    };
}]);

推荐答案

我分叉了您的plunkr,并弄乱了它.我认为它可以按照您现在想要的方式工作.

I forked your plunkr and messed around with it. I think it works the way you want now.

http://plnkr.co/edit/1y8jE0SLuJK6XTNRBKF3?p=preview

主要解决的问题是按其索引对dom元素列表进行排序,然后将$ index添加到该元素的数据索引attr.

Mainly what fixed it was sorting the list of dom elements by their index, and to do that I added the $index to a data-index attr on the element.

这篇关于当新项目添加到模型时,对所有项目进行ng-repeat更改排序顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆