0

I want to loop over an object's property. Also, there should be a two-way data binding so that any change will change the Object as well.

Both key and value of the object property can be changed from UI and should reflect in the object's structure.

I am able to do it for object's value with ng-model="contents[index]"

but how to do that with object property key e.g. interface in the object will change if I change it on UI.

$scope.contents = {
          "interface": "GigabitEthernet",
          "interfaceNumber": "1",
          "BGPneighborIp": "00.0.112.499",
          "BGPremoteAs_[1]": "701",
          "BGPneighborIp_[2]": "8.3.112.170",
          "BGPremoteAs_[2]": "702"
        }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<tbody>
<tr ng-repeat="(index, p1) in contents">
<td>
<input class="form-control" type="text" ng-model="index">
</td>
<td>
<input class="form-control" type="text" ng-model="contents[index]">
</td>
</tr>
</tbody>

2
  • Maybe this SO will help. The consensus there is you can't. I would suggest changing your data-structure so modifying the object's key isn't needed. Commented Nov 8, 2016 at 9:51
  • @ ste2425 - I have JSON structure behind. as per the design. I am required to loop on the different objects and show it on UI. key and values can be changed from UI and should reflect on JSON behind. There is no save or submit to change the values, that's why need two way binding. converting object into array will require to extra efforts to merge it again in JSON. Commented Nov 8, 2016 at 11:47

1 Answer 1

1

Try this solution:

angular.module('app',[]).controller('test',['$scope', function($scope){  
  $scope.contents = {    
          "interface": "GigabitEthernet",
          "interfaceNumber": "1",
          "BGPneighborIp": "00.0.112.499",
          "BGPremoteAs_[1]": "701",
          "BGPneighborIp_[2]": "8.3.112.170",
          "BGPremoteAs_[2]": "702"
   };  

   $scope.arr = [];
   for(var prop in $scope.contents)  
      $scope.arr.push({oldKey:prop, newKey:prop});

   $scope.change = function(item){                                   
      $scope.contents[item.newKey] = $scope.contents[item.oldKey];          
      delete $scope.contents[item.oldKey];
      item.oldKey = item.newKey;
  }
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller='test'>
    <input ng-repeat-start='item in arr' type='text' ng-model="item.newKey" ng-change='change(item)'>
    <input type='text' ng-model="contents[item.oldKey]" >  
    <br ng-repeat-end>  
  <p>{{contents|json}}</p>
</div>

Sign up to request clarification or add additional context in comments.

8 Comments

It's working but the keys are changing the position as per sorting order. e.g if you change BGPneighborIp to aBGPneighborIp, it will become the 4th element. Which is not good from UI perspective if we have a huge table. is there any solution apart from sorting?
At this case, you should have projection/copy of $scope.contents, for example, array like [{key:'interface', value:'GigabitEthernet'},,,], and reflect any changes at this copy to $scope.contents and vice versa
even we have a copy , ng-repeat on the object will maintain the sorting order.so changing any key will change it's position.
No, at ng-repeat we will iterate through array indeed, so can control order and any changes will prolong to object, behind the scene.
Yes, so we need to convert it to an array and save it back to object once done. The array is used for ng-repeat to maintain the order. I think this is the solution.right?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.