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

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

问题描述

我创建了一个tessellate"指令,让您可以包装多个 div.

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

</tessellate>

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

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

问题在于,当模型改变时,ng-repeat 使用 div 在 DOM 中出现的顺序,而不是在模型中出现的顺序来重绘元素.您可以看到,首先对项目进行了正确排序,然后单击 Add 后,它正在对第一列的项目进行水平排序,然后是下一列的项目,依此类推.

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

var app = angular.module('app', []);app.controller('itemController', ['$scope', function ($scope) {$scope.items = [{ id:"1", Name:"Item1", Summary:"这是Item1的摘要" },{ id:"2", Name:"Item2", Summary:"这是 Item2 的摘要.项目 2 上的一些额外文本以测试不同的高度."},{ id:"3", Name:"Item3", Summary:"这是Item3的摘要" },{ id:"4", Name:"Item4", Summary:"这是 Item4 的摘要.项目 4 上的一些额外文本以测试不同的高度.},{ id:"5", Name:"Item5", Summary:"这是 Item5 的摘要.item 5 上的一些额外文本以测试不同的高度.item 上的一些额外文本以测试不同的高度."},{ id:"6", Name:"Item6", Summary:"这是Item6的摘要" },{ id:"7", Name:"Item7", Summary:"这是 Item7 的摘要.在 item 7 上有一些额外的文字来测试不同的高度."},{ id:"8", Name:"Item8", Summary:"这是Item8的摘要" },{ id:"9", Name:"Item9", Summary:"这是Item9的总结.item 9上的一些额外文字以测试不同的高度."},{ id:"10", Name:"Item10", Summary:"这是 Item10 的摘要.item 10 上的一些额外文本以测试不同的高度."},{ id:"11", Name:"Item11", Summary:"This is the summary of Item11" },{ id:"12", Name:"Item12", Summary:"这是 Item12 的摘要.item 上的一些额外文本以测试不同的高度."},{ id:"13", Name:"Item13", Summary:"This is the summary of Item13" },{ id:"14", Name:"Item14", Summary:"这是 Item14 的摘要.item 上的一些额外文本以测试不同的高度."},{ id:"15", Name:"Item15", Summary:"这是 Item15 的摘要.item 上的一些额外文本以测试不同的高度.item 上的一些额外文本以测试不同的高度."},{ id:"16", Name:"Item16", Summary:"This is the summary of Item16" },{ id:"17", Name:"Item17", Summary:"这是 Item17 的摘要.item 上的一些额外文本以测试不同的高度."},{ id:"18", Name:"Item18", Summary:"这是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 () {返回 {限制:'E',替换:真的,转置:真实,范围: {列:'='},控制器:['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {$scope.numberToArray = 函数 (num) {返回新数组(数量);};}],链接:函数(范围,元素,属性,ctrl){范围.$watch(函数(){返回 elem.children().first().height();}, 功能(高度){如果(高度> 0){var 容器 = elem.children();var transcludedDivsContainer = container.first();var targetColumns = container.eq(1).children();//将嵌入的 div 一次一个添加到最短的列中.angular.forEach(transcludedDivsContainer.children(), 函数 (div) {var shortCol = null;angular.forEach(targetColumns, function (col) {col = angular.element(col);if (shortCol === null || col.height() 

解决方案

我分叉了你的 plunkr 并搞砸了它.我认为它现在按照您想要的方式工作.

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

主要修复的是按索引对 dom 元素列表进行排序,为此我将 $index 添加到元素上的数据索引属性.

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>

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.

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

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.

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

解决方案

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

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天全站免登陆