1

I have a json that I want in a ng-repeat show an input per item for editing.

The json:

$scope.setup.configuration = {
    "filename": "configuration", 
    "fileversion": "01.00.0000"
};

The directive (uses "=" in scope for two ways binding):

 app.directive("kSetupOption", ['$rootScope',function ($rootScope) {
        return {
            scope:{
                key:"=",
                option:"="
            },
            restrict: 'E',
            template:'<p>{{key}}: <input ng-model="option" /></p>',
            link: function (scope, element, attrs) {
              }
            }
    }]);

The problem is that the 2 way binding works correctly with this:

<input ng-model="setup.configuration.filename">

But not with this code using the directive:

<k-setup-option
    ng-repeat="(key , option) in setup.configuration" 
    option="option" 
    key="key" ></k-setup-option>

Please see the demo in Plunker . thanks.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
Fabrice
  • 161
  • 1
  • 8
  • plunker. link is not working please edit it – v8-E May 14 '18 at 06:19
  • @Fabrice As `ng-repeat` is a directive every time it iterates, it generates new instance has it own scope, tough you mention `=` its doesn't matter . updated your plunker https://plnkr.co/edit/HdclYxw1mCAgpQYR38Ia?p=preview – super cool May 14 '18 at 07:27

1 Answers1

0

Move the ng-repeat inside the directive:

angular.module('app', [])
.directive("kSetupOption", function () {
    return {
            scope:{
                config:"<",
            },
            restrict: 'E',
            template:`<p ng-repeat="(key,option) in config">
                       {{key}}: <input ng-model="config[key]" />
                      </p>`,
            link: function (scope, element, attrs) {
            }
    };
})
.controller('ctrl', function($scope) {
  var MC = $scope;
  MC.setup = {};
  MC.setup.configuration = {
            "filename": "configuration", 
            "fileversion": "01.00.0000"
  };
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="ctrl">
    
    <k-setup-option config="setup.configuration"></k-setup-option>
  
    <h2>setup.configuration:</h2> 
    <div style="background-color:#f9f0b3">{{setup.configuration}}</div>  
</body>

When using ng-repeat, binding ng-model to primitives (ng-model="option") creates the data hiding problem described in "What are the nuances of scope prototypal / prototypical inheritance in AngularJS?"

Avoid that by binding ng-model to a property of an object, i.e, config[key].

georgeawg
  • 48,608
  • 13
  • 72
  • 95