javascript - AngularJS - implementing "undo" with angular.copy fails - Stack Overflow

Following issue: Let's say, we have an object like this:$scope.Something = { 'a' : { obj

Following issue: Let's say, we have an object like this:

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

This Something-object is also rendered in the view as follows:

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

The user wants to edit Something.a. For this, we show him a form. Before the form is shown, I save the current Something.a as a copy:

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

Now, if the user clicks "Cancel", it gets:

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

But since then, the association seems to disappear. No matter, what changes the user now makes to Something.a, the view doesn't get updated.

Why?

I know, what the equality of objects is (for example, that { object1: true } != {object1 : true} but still I cannot understand, why it doesn't work.

Following issue: Let's say, we have an object like this:

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

This Something-object is also rendered in the view as follows:

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

The user wants to edit Something.a. For this, we show him a form. Before the form is shown, I save the current Something.a as a copy:

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

Now, if the user clicks "Cancel", it gets:

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

But since then, the association seems to disappear. No matter, what changes the user now makes to Something.a, the view doesn't get updated.

Why?

I know, what the equality of objects is (for example, that { object1: true } != {object1 : true} but still I cannot understand, why it doesn't work.

Share Improve this question asked Sep 17, 2013 at 3:46 Liglo AppLiglo App 3,8294 gold badges31 silver badges55 bronze badges 1
  • could you share your fiddle please – Ajay Singh Beniwal Commented Sep 17, 2013 at 6:57
Add a ment  | 

5 Answers 5

Reset to default 2

If you can make $scope.Something an array, then you can edit the copy and then update the array when the changes are saved. It still provides an undo, but in reverse of how you presented it.

fiddle here: http://jsfiddle/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;
    }
}

Update There is an alternate syntax for ng-repeat that can be used to enumerate dictionaries to get their key. Using this syntax, you can use the data structure you describe in the question

fiddle here: http://jsfiddle/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" ....>

If the copy source is ng-repeat iterative item, you should use

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

insteads of

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

Otherwise, your data-binding dom is not tracking because the $$hashkey of the iterative item was erased by the misuse copy statement.

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

it seems a bit odd but if you can save the original array $scope.Something then on canceling you can rebind it.

 // 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.

Non destructive form editing: http://egghead.io/lessons/angularjs-angular-copy-for-deep-copy

Synopsis:

  • create a pointer to the object that the user clicked edit
  • create a copy of object that user edits and can decide to save|cancel

I'm not sure if it has to do with the fact that you are copying a copy, or what, but here is a working plunker

Copy Example Plunker

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744897982a4599809.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信