9

I have an array of strings, and I want each of the strings to be bound to an input.

However, editing the input doesn't seem to update the array (isolated scope issues maybe?).

Suggestions?

function Ctrl($scope) {
  $scope.fruits = ['Apple', 'Mango', 'Banana', 'Strawberry'];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
  <div ng-controller="Ctrl">

    <div style="margin: 20px 0" ng-repeat="fruit in fruits">
      <input type="text" ng-model="fruit" />
    </div>

    Fruits: {{fruits}}

  </div>
</div>

2 Answers 2

23

You need the array reference which you can get from $index. Note, however, that this won't work if any filtering is done on the ng-repeat, as the indexing then is based on the filtered array, not the original.

<div style="margin: 20px 0" ng-repeat="fruit in fruits track by $index">
      <input type="text" ng-model="fruits[$index]" />
</div>

DEMO

Sign up to request clarification or add additional context in comments.

10 Comments

so, does this mean that fruit is a copy and not the actual array element in the OP's syntax ?
@gaurav5430 it's the element of the array but it's assigned in a child scope and since primitives don't have inheritance then yes it could be considered a "copy"
@gaurav5430 think of it like var a=[1,2,3]; b=a[0];//1 then do b=99 doesn't change array a
i tried your code, i am not sure why but everytime i type a single letter, the focus is lost from the input and i have to bring focus again for typing another letter.
@gaurav5430 yes... I forgot to put in track by . try demo link, works fine
|
2

Ok, so it seems to me like a case of

'ng-model requires a dot in the model name to work correctly with the scope, otherwise it would create a local scope'

What i would suggest is to change your data structure from plain strings to objects containing the strings as a property, something like :

 $scope.fruits = [
    {'title':'Apple'},
    {'title':'Mango'},
    {'title':'Banana'},
    {'title':'Strawberry'},
    ];

Now, when you bind it to ng-model like this

<div style="margin: 20px 0" ng-repeat="fruit in fruits">
      <input type="text" ng-model="fruit.title" />
</div>

then it will not create any local/child scope, instead it would be able to bind to the title property on the items in the fruits array.

example fiddle: http://jsfiddle.net/HB7LU/24008/

2 Comments

sure if items are objects but for array you don't have to restructure and create objects. The idea behind using dot is to have an object in ng-model but an array is also an object. The whole issue is about prototypal inheritance and array and object literal both have inheritance
alternate way to look at it is ng-model="fruit['title']" and syntax is the same as using array ... [] is equivalent to dot

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.