Difficulty with ng-model, ng-repeat, and inputs Difficulty with ng-model, ng-repeat, and inputs angularjs angularjs

Difficulty with ng-model, ng-repeat, and inputs


This seems to be a binding issue.

The advice is don't bind to primitives.

Your ngRepeat is iterating over strings inside a collection, when it should be iterating over objects. To fix your problem

<body ng-init="models = [{name:'Sam'},{name:'Harry'},{name:'Sally'}]">    <h1>Fun with Fields and ngModel</h1>    <p>names: {{models}}</p>    <h3>Binding to each element directly:</h3>    <div ng-repeat="model in models">        Value: {{model.name}}        <input ng-model="model.name">                             </div>

jsfiddle: http://jsfiddle.net/jaimem/rnw3u/5/


Using Angular latest version (1.2.1) and track by $index. This issue is fixed

http://jsfiddle.net/rnw3u/53/

<div ng-repeat="(i, name) in names track by $index">    Value: {{name}}    <input ng-model="names[i]">                         </div>


You get into a difficult situation when it is necessary to understand how scopes, ngRepeat and ngModel with NgModelController work. Also try to use 1.0.3 version. Your example will work a little differently.

You can simply use solution provided by jm-

But if you want to deal with the situation more deeply, you have to understand:

  • how AngularJS works;
  • scopes have a hierarchical structure;
  • ngRepeat creates new scope for every element;
  • ngRepeat build cache of items with additional information (hashKey); on each watch call for every new item (that is not in the cache) ngRepeat constructs new scope, DOM element, etc. More detailed description.
  • from 1.0.3 ngModelController rerenders inputs with actual model values.

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').

How your example "Indexing into the array" works:

  • you enter letter 'f' into input;
  • ngModelController changes item in names array => `names == ['Samf', 'Harry', 'Sally'];
  • $digest loop is started;
  • ngRepeat can't find 'Samf' in cache;
  • ngRepeat creates new scope, adds new div element with new input (that is why the input field loses focus - old div with old input is replaced by new div with new input);
  • new values for new DOM elements are rendered.

Also, you can try to use AngularJS Batarang and see how changes $id of the scope of div with input in which you enter.