Levent Esen
Levent Esen

Reputation: 579

Cannot modify the textbox that is generated by ng-repeat

I cannot modify the textboxes that are generated by the ng-repeat. It is also a little complicated because of the parent/child scopes.

Link: http://jsfiddle.net/tzXn2/

The script:

function ConfigController($scope)
{
    $scope.config = {"key1":["a","b","c"]};
}
function SettingController($scope)
{
    var configKey = null;
    function update() {
        $scope.items = $scope.config[configKey];
    }
    $scope.init = function(key) {
        configKey = key;
        update();
    };
    $scope.$watch('config', update, true);
}

The markup:

<div ng-app ng-controller="ConfigController">
    Config: {{config}}
    <div ng-controller="SettingController" ng-init="init('key1')">
        Items: {{items}}
        <div ng-repeat="item in items">
            <input ng-model="item" type="text"/>
        </div>
    </div>
</div>

Upvotes: 2

Views: 3459

Answers (3)

Manoj
Manoj

Reputation: 5087

Instead of binding to primitives, binding to object has the behaviour you want.

 $scope.config = {"key1":[{value : "a"},{value:"b"},{value : "c"}]};

The binding will be

<div ng-repeat="item in items">
    <input ng-model="item.value" type="text"/>
</div>

The following link explains why this works

Do not bind to primitives

The answer by Artem Andreev to another question explains the behaviour in a nice way. Reproducing the relevant part :

How your example "Binding to each element directly" works for AngularJS 1.0.3:

  • you enter letter 'f' into input;
  • ngModelController changes model for item scope (names array is not changed) => name == 'Samf', names == ['Sam', 'Harry', 'Sally'];
  • $digest loop is started;
  • ngRepeat replaces model value from item scope ('Samf') by value from unchanged names array ('Sam');
  • ngModelController rerenders input with actual model value ('Sam').

Upvotes: 2

Chandermani
Chandermani

Reputation: 42669

The ng-repeat binding creates child scope for each item it creates. On this child scope you can read all types from parent scope, but if you change primitive types like string, integer and boolean it creates a new object on the child scope, so the changes would not reflect on parent scope model.

You ng-model should work with a dot notation or complex object, if you want to use it in ng-repeat. Something like

<div ng-repeat="item in items">
            <input ng-model="item.text" type="text"/>
        </div>

Secondly you are trying to change the model on which ng-repeat is binding itself. Any change to that will cause ng-repeat to run again, and rebind the old value from the parent scope.

Upvotes: 1

Sebastien C.
Sebastien C.

Reputation: 2109

you need to put your ng-model reference in an object. Angular cannot store value in an array I think.

add a $scope.value : {key1: {a: 'a', b: 'b', c: 'c'}} to store the value of each of your field and then bind the input with ng-model="value['key1'][item]"

Like this : http://jsfiddle.net/tzXn2/3/

By the way, you could replace all the update/watch stuff by just one line in your init:

$scope.items = $scope.config[key];

Upvotes: 1

Related Questions