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

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

我有一个对象数组:

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

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

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

我发现数组中的对象在重新排序时通过 2 路绑定(bind)根据位置(列/行)相应地更改其属性,但它们的索引不反射(reflect)更改。例如,如果用户交换图 block 1(索引 0)和 2(索引 1),属性将被更新,但对象永远不会交换数组中的位置。

Here是我的 fiddle ,它演示了当您在网格中移动图 block 时,“行”和“列”属性会发生变化,但索引永远不会改变。是否可以根据 ng-repeats 项目的当前位置对集合重新排序?

示例: 用户将图 block 2 拖动到图 block 1 的位置。图 block 2 现在应该成为索引 0,图 block 1 现在应该成为索引 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;
}

使用 track by 进行 ng-repeat

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

关于javascript - ng-repeat 可以在重新排序期间修改内部集合的索引吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26921824/

相关文章:

php - PHP的多维数组键成一个单一的数组?

php - AngularJS 表单验证 - 跳过预填充的输入字段

javascript - 无法将对象值从 javascript 传递到 Controller

javascript - 是什么阻止我的 redux 操作正常工作?

JavaScript 拆分由下划线分隔的值并计算 SUM

javascript - 多个 Kendo 编辑器在 Chrome 上粘贴屏幕截图

c# 左移字节数组中的半字节

c - 将数组大小声明为 a[N+1]

angularjs - bower-angular-bootstrap3 存储库移到了哪里?

angularjs - 使用 CellTemplate 和指令在 ng-grid 的单元格中使用 jQuery Sparkline