AngularJS - 使用angular.copy实现“撤消”失败

时间:2013-09-17 03:46:05

标签: javascript object angularjs

以下问题:假设我们有一个像这样的对象:

$scope.Something = { 'a' : { object... }, 'b' : { another object... } }

这个Something-object也在视图中呈现如下:

<div ng-repeat="s in Something">{{ Something[s].someProperty }}</div>

用户想要修改 Something.a 。为此,我们向他展示一张表格。在显示表单之前,我将当前的 Something.a 保存为副本:

$scope.copyForUndo= angular.copy($scope.Something.a);

现在,如果用户点击“取消”,则会获得:

$scope.Something.a = angular.copy($scope.copyForUndo);

但从那以后,协会似乎消失了。无论用户现在对Something.a进行了哪些更改,视图都不会更新。

为什么?

我知道,对象的相等性是什么(例如, {object1:true}!= {object1:true} ,但我仍然无法理解,为什么它不起作用。< / p>

5 个答案:

答案 0 :(得分:2)

如果可以使$scope.Something成为数组,则可以编辑副本,然后在保存更改时更新阵列。它仍然提供撤消,但与你呈现它的方式相反。

在这里摆弄:http://jsfiddle.net/GYeSZ/1/

function MyCtrl($scope) {
    $scope.Something = [
        { name: "Aye", desc: new Date() },
        { name: "Bee", desc: new Date() },
        { name: "See", desc: new Date() }
    ];

    $scope.edit = function(idx) {
        $scope.copy = angular.copy($scope.Something[idx]);
        $scope.idx = idx;
    }

    $scope.save = function() {
        $scope.Something[$scope.idx] = angular.copy($scope.copy);
        $scope.cancel();
    }

    $scope.cancel = function() {
        $scope.copy = null;
        $scope.idx = -1;
    }
}

<强>更新 ng-repeat有一种替代语法,可用于枚举字典以获取其密钥。使用此语法,您可以使用您在问题中描述的数据结构

在这里摆弄:http://jsfiddle.net/GYeSZ/3/

function MyCtrl($scope) {

    $scope.edit = function(key) {
        $scope.copy = angular.copy($scope.Something[key]);
        $scope.key = key;
    }

    $scope.Something = {
        "a": { name: "Aye", desc: new Date() },
        "b": { name: "Bee", desc: new Date() },
        "c": { name: "See", desc: new Date() }
    };

    $scope.save = function() {
        $scope.Something[$scope.key] = angular.copy($scope.copy);
        $scope.cancel();
    }

    $scope.cancel = function() {
        $scope.copy = null;
        $scope.key = null;
    }
}

<强> HTML

<div ng-repeat="(key, value) in Something" ....>

答案 1 :(得分:2)

如果复制源是ng-repeat迭代项,则应使用

angular.copy($scope.copyForUndo, $scopy.sourceItem)

代替

$scope.sourceItem = angular.copy($scope.copyForUndo)

否则,您的数据绑定dom不会跟踪,因为$$hashkey 重复项目被滥用复制声明删除。

https://github.com/angular/angular.js/blob/g3_v1_2/src/Angular.js#L777

答案 2 :(得分:1)

看起来有点奇怪但是如果你可以保存原始数组$ scope.Something然后取消你可以重新绑定它。

 // saving original array to get the original copy of edited object
 var originalArrayCopy = angular.copy($scope.Something);
 ............
 // When user clicks cancel then simply filter the originalArray to get the original copy, here i am assuming there is a field in object which can uniquely identify it. 
// var originalObject = originalArrayCopy .filter(function(elm)
   {
       if(editedObject.Id == elm.Id)
              return elm;
   } );
 // once i get the original object , i can rebind it to the currentObject which is being edited.

答案 3 :(得分:1)

非破坏性表单编辑:http://egghead.io/lessons/angularjs-angular-copy-for-deep-copy

剧情简介:

  • 创建指向用户点击的对象的指针
  • 创建用户编辑并可决定保存|取消
  • 的对象副本

答案 4 :(得分:0)

我不确定这是否与您复制副本或什么有关,但这是一个有效的插件

Copy Example Plunker