-2

I have this plunkr here, which displays an editable table.

Following is the HTML code for table:

  <body ng-controller="MainCtrl">
    <table style="width:100%">
  <tr>
    <th>Name</th>
    <th>Is enabled?</th>        
    <th>Points</th>
  </tr>
  <tr ng-repeat="fooObject in fooObjects | orderBy:'points'">
    <td><input ng-model="fooObject.name" ng-disabled="fooState!='EDIT'"/></td>
    <td><input ng-model="fooObject.isEnabled" ng-disabled="fooState!='EDIT'"/></td>     
    <td><input ng-model="fooObject.points" ng-disabled="fooState!='EDIT'"/></td>
    <td>
      <a href="#" ng-click="handleEdit(fooObject, 'EDIT', $index)">Edit</a>
      <a href="#" ng-click="handleEditCancel(fooObject, 'VIEW', $index)">Cancel</a>
    </td>
  </tr>
</table>
  </body>

I would like the Cancel link in the row display the previous state of the fooObject as if that row was never touched.

Following is the code in the AngularJS controller, which seems to work as long as I don't have "orderBy:'points'" in the ng-repeat expression, but doesn't work otherwise:

app.controller('MainCtrl', function($scope) {
  $scope.fooObjects = [
    {"name": "mariofoo", "points": 65, "isEnabled": true}, 
    {"name": "supermanfoo", "points": 47, "isEnabled": false}, 
    {"name": "monsterfoo", "points": 85, "isEnabled": true}
    ];

    $scope.fooState = 'VIEW';

    $scope.originalFooObject = null;
    $scope.handleEdit = function(fooObject, fooState, index){
       $scope.originalFooObject = angular.copy(fooObject);
       $scope.fooObject = fooObject;
       $scope.fooState = fooState;
    }

    $scope.handleEditCancel=function(fooObject, fooState, index){
      $scope.fooObjects[index] = $scope.originalFooObject;
       $scope.originalFooObject=null;
       $scope.fooState = fooState;
    }


});

Could somebody help me understand how get it resolved?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
skip
  • 12,193
  • 32
  • 113
  • 153
  • This question does not show any research effort; it is unclear or not useful? Really? Please guide me through a useful link as I could not find any that solved the given issue. Please tell me what was not understood in the question? Thank you. – skip Dec 25 '14 at 17:46
  • 3
    I think people react to your last sentence. Typically good questions show some effort and specific issue. You have some of that in the plunker, but you should bring relevant parts of it and post them in the question itself. – New Dev Dec 25 '14 at 18:03
  • @NewDev: Yes that could be the issue. I actually thought that it would save time resolving the issue. I've updated the post. Thanks. – skip Dec 25 '14 at 18:16
  • 1
    Having a plunker is always good - but the question should always stand on its own. It also forces you to create a minimal reproducible example of your problem. – New Dev Dec 25 '14 at 18:24
  • Anyway, specifically about your question - do you want to "save"/"cancel" per row? What is the trigger to "save"? – New Dev Dec 25 '14 at 18:26
  • @NewDev: In the given plunker I only need to handle the `Cancel` link properly, which is not happening at the moment. For example, when I make the `fooObject.points` property of a particular `fooObject` in a row dirty, and then try to cancel that change using the `Cancel` button, it doesn't revert back the value of 'fooObject.points' back to its previous value. – skip Dec 25 '14 at 18:36

1 Answers1

5

You were right to use master/copy of the object. But you restore the original value out of context of your editable row. And so, it doesn't work with orderBy because orderBy changes the index and you end up updating (rather than resetting) a different element. But it wouldn't work even without 'orderBy': try edit one row but hitting cancel on another. Do you see why it doesn't work?

There are a number of ways to do this. For example, your fooObjects can contain the copy of each row under edit:

$scope.handleEdit = function(fooObject){
  fooObject.$original = fooObject.$original || angular.copy(fooObject);
  $scope.fooState = "EDIT";
}

$scope.handleEditCancel = function(fooObject){
   angular.copy(fooObject.$original, fooObject);
   $scope.fooState = "VIEW";
}

(notice how you don't need index)

Here's your updated plunker

New Dev
  • 48,427
  • 12
  • 87
  • 129