当对底层数组进行更改时,ng-repeat不重新排序

时间:2014-12-05 16:35:02

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

我正在使用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();,但是在我执行此操作之后,页面上的订单没有更新,甚至保持在更改状态虽然$scope.rules回到它的状态不变。如何让显示屏恢复原始状态?

1 个答案:

答案 0 :(得分:4)

在进一步观察之后,看起来.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);
            });

一切顺利。