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>
Mudit bhaintwal
  • 528
  • 1
  • 7
  • 21
  • Maybe [this SO](http://stackoverflow.com/questions/23643592/how-to-bind-angularjs-objects-to-their-keys-and-values) 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. – ste2425 Nov 08 '16 at 09: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. – Mudit bhaintwal Nov 08 '16 at 11:47

1 Answers1

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>
Slava Utesinov
  • 13,410
  • 2
  • 19
  • 26
  • 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? – Mudit bhaintwal Nov 09 '16 at 06:27
  • 1
    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 – Slava Utesinov Nov 09 '16 at 07:15
  • even we have a copy , ng-repeat on the object will maintain the sorting order.so changing any key will change it's position. – Mudit bhaintwal Nov 09 '16 at 07:17
  • No, at `ng-repeat` we will iterate through array indeed, so can control order and any changes will prolong to object, behind the scene. – Slava Utesinov Nov 09 '16 at 07:21
  • 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? – Mudit bhaintwal Nov 09 '16 at 07:26
  • Yes, but when you change some property at your object at other places of your code, you should not forget to make corresponding changes at array - it is big minus, because, at this case, you lose direct correlation between view and model. – Slava Utesinov Nov 09 '16 at 07:30
  • Also problem with that, Angular not quarantee order for `ng-repeat` of object properties, read section [Iterating over object properties](https://code.angularjs.org/1.3.20/docs/api/ng/directive/ngRepeat) – Slava Utesinov Nov 09 '16 at 07:56
  • @Mudit, I updated answer to "array" approach. Now order's problem is solved. – Slava Utesinov Nov 10 '16 at 06:11