【问题标题】:ng-repeat not reordering when change is made to underlying array对底层数组进行更改时,ng-repeat 不会重新排序
【发布时间】:2014-12-05 16:35:02
【问题描述】:

我正在使用 ui.sortable 来显示可重新排序的项目列表。我得到这样的数据:

    context.rules.getAll()
        .then(
            function (data) { // success
                $scope.rules = data;
                cachedRules = data.slice();
                $scope.loaded = true;
            },
            function (response) { // failure
                console.log(response);
            });

我使用cachedRules,因此我可以将正在重新排序的数组与原始数组进行比较,并检测是否进行了更改。我的观点是这样的:

    <tbody ui-sortable="sortableOptions" ng-model="rules">
        <tr ng-repeat="rule in rules|orderBy:'RuleSequence'" ng-class="{'unsortable': !reorder, 'inactive': !rule.Active}">
            <td><i ng-show="reorder" class="fa fa-reorder"></i></td>
            <td>{{rule.RuleSequence}}</td>
            <td>{{rule.ProxyType}}</td>
            <td>{{rule.ProxyDesc}}</td>
            <td>
                <i class="fa fa-download" title="Download CSV" ng-click="getAssignments(rule.RuleID)"></i>
                <i class="fa fa-gears" title="Edit Rule" ng-click="editRuleShow(rule)"></i>
            </td>
        </tr>
    </tbody>

每当重新排序某些内容时,都会调用此代码,以便更新 RuleSequence(我在 OrderBy 中使用的):

            $scope.rules.map(function (r) {
                r.RuleSequence = $scope.rules.indexOf(r) + 1;
                return r;
            });

如果$scope.rules 的顺序与cachedRules 不同,则会启用“保存”按钮。这一切都很完美。

但是,我想要一个“取消”按钮,单击该按钮会将页面上的显示恢复为原始顺序。鉴于我存储了原始数据的副本,这应该很容易,我使用 ng-click 来执行$scope.rules = cachedRules.slice();,但是在我这样做之后订单不会在页面上更新,即使@也保持在它的更改状态987654329@ 恢复到未更改的状态。如何让显示恢复到原来的顺序?

【问题讨论】:

  • 我在 ui-sortable 上有一个非常相似的问题。我最终不得不将列表设置为一个空数组( list = [] ),让 angular 完成消耗事件发生的任何循环,然后将其设置回新数组。我使用超时功能做到了这一点。 IE设置为空。设置一个超时函数,在 500 毫秒后设置为正确的值。但我猜有某种角度的电话说“消费所有当前事件”或类似的事情。
  • 试过了,而不是$scope.rules = cachedRules.slice(); 我做了$timeout(function () { $scope.rules = []; $scope.rules = cachedRules.slice(); }, 500); 但是没有变化。

标签: angularjs angular-ui angular-ui-sortable


【解决方案1】:

进一步观察后,看起来 .slice() 并没有像我想象的那样进行深度复制(我对 javascript 的经验不足)。因此,当我最初获取数据并设置 cachedData 时,数组本身不是引用,但数组内部的对象仍然是,所以当我在这里更新它们时

            $scope.rules.map(function (r) {
                r.RuleSequence = $scope.rules.indexOf(r) + 1;
                return r;
            });

它同时更新了两者,因此 cachedRules 将具有更新的 RuleSequence。当我单击“取消”并将其设置回 cachedRules 时,RuleSequence 将保持不变。因此,当我使用 loDash 进行适当的深拷贝时

    context.rules.getAll()
        .then(
            function (data) { // success
                $scope.rules = data;
                cachedRules = _.cloneDeep($scope.rules);
                $scope.loaded = true;
            },
            function (response) { // failure
                console.log(response);
            });

一切顺利。

【讨论】:

  • 感谢您跟进解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多