Reputation: 3058
In my controller:
$scope.mytest = [1,2,3];
My view:
<div ng-repeat="foo in mytest">
{{foo}}
<input type="text" ng-model="mytest[$index]" name="$index" />
</div>
{{ mytest | json }}
When I load the page it renders this:
I can change the value, and the binding updates all the values:
The only problem, is the form field loses focus. When ng-model
updates the scope's values, it causes ng-repeat to manipulate the dom, and the fields lose focus after each key press. I have to click back inside the field between each keypress to enter a value with length more than 1 character.
What I'm trying to accomplish here is to render a text field for each value of an array. Updating the text field should update the scope values, and also update all places I'm displaying those values within the view, both inside & outside of the ng-repeat
Upvotes: 1
Views: 345
Reputation: 3058
Figured it out. I changed my array to be an array of objects with IDs:
$scope.mytest = [{id:1, title:'one'}, {id:2, title:'two'}];
Then I prevented ng-repeat from removing & re-inserting a dom node when it changes:
<div ng-repeat="foo in mytest track by foo.id">
My previous attempt from the original post fails. In this example illustrating why, you can see that Angular can't discern what changes were made:
[1,2,3] // point A
[2,2,3] // point B
Angular has no way of knowing what took place to get from point A to B. Did I edit the first value? Remove it & and insert a new value? Make multiple edits that cancel each other out?
In this example, Angular is able to discern what happened to get from Point A to B:
$scope.mytest = [{id:1, title:'one'}, {id:2, title:'two'}]; // point A
$scope.mytest = [{id:1, title:'two'}, {id:2, title:'two'}]; // point B
In this example I use the "value object" design pattern. I wrap my scalar values in an object which has an identifier that is immutable, while the wrapped value remains mutable.
Combined with the "track by" syntax of ng-repeat
, it allows Angular to discern between an add & subsequent removal versus an edit. ng-repeat
can then directly update the bindings in the isolate scope, as opposed to redrawing the whole darn page.
Upvotes: 1