在重新排序期间,ng-repeat可以修改内部集合的索引

时间:2014-11-14 02:13:45

标签: javascript arrays angularjs ng-repeat angular-ngmodel

我有一个对象数组:

$scope.widgets = [{
    col: 0,
    name: "Tile 1"
}, {
    col: 1,
    name: "Tile 2"
}, {
    col: 2,
    name: "Tile 3"
}];

每个对象都表示为网格中的小部件。对于ng-repeat的每次迭代,都会在其各自的位置(col,row)中创建一个新的小部件:

    <li gridster-item="widget" ng-repeat="widget in widgets">

我发现数组中的对象在重新排序时通过双向绑定在位置(col / row)方面相应地更改其属性,但它们的索引不反映更改。例如,如果用户交换了tile 1(索引0)和2(索引1),则属性将被更新,但对象永远不会交换数组中的位置。

Here是我的小提琴,它演示了在网格周围移动图块时属性'row'和'col'的变化,但索引永远不会改变。是否可以根据ng-repeats项目的当前位置对集合进行重新排序?

实施例: 用户将图块2拖动到图块位置。 Tile 2现在应该成为索引0,tile 1现在应该是索引1;

1 个答案:

答案 0 :(得分:1)

基本的解决方案是你需要定义一个回调,当你停止拖动其中一个数组时,它将对$scope.widgets数组进行排序。

我有forked your jsFiddle完整的解决方案,但以下是重点:

指定拖动回调

将以下键添加到您的gridster选项中:

draggable: {
    enabled: true,
    stop: function (event, $element, widget) {
        sortWidgets();
    }
}

编写排序代码

如果您使用的是underscorelodash,则可以使用.sortBy()功能轻松完成此操作。或者,您也可以在本机JS中执行此操作:

function sortWidgets() {
    $scope.widgets.sort(function (widget1, widget2) {
        return position(widget1) - position(widget2);
    });
}

function position(widget) {
    return (widget.row || 0) * $scope.gridConfig.columns + widget.col;
}

ng-repeat

使用track by

假设您的实际小部件更复杂,我建议您向track by添加ng-repeat表达式,以便在之后为小部件重用相同的DOM节点排序为之前排序的那个。您现在可以添加这个小的性能优化,而不是等到事情变慢。