Jay
Jay

Reputation: 19857

Modifying an array within an object that's displayed in a ng-repeat

I'm trying to update a $scope object's array that is displayed in a ng-repeat on the page using input elements containing the array's contents. The plunker example can be found here: Plunker demo (Basic, stripped down example of my problem)

I have the following settings object defined:

$scope.settings = {
  list: ['list item one', 'list item two', 'list item three']
};

and I am representing the data on the page like so:

<ul> 
  <li ng-repeat="item in settings.list">
    <input type="text" 
           value="{{item}}" 
           ng-model="singleItem"
           ng-change="settings.list[$index] = singleItem" />
    <a href="javascript:void(0)">delete</a>
  </li>
</ul>

My goal is to initially populate the <input> fields with the contents of $scope.settings.list and whenever an item is changed update the array, but I haven't figured out how to in the view. Omitting the ng-model and ng-change on the input properly renders the input vale in the text boxes, but then the array isn't modified when changes are made.

Side Note: In the Plunker example I have $watch on the settings object. In my actual code, this is used to update a "settings cookie" using the $cookies module. Cookies have been omitted in the example, but for debugging purposes I have left the watch in.

Upvotes: 2

Views: 6857

Answers (1)

Josh David Miller
Josh David Miller

Reputation: 120513

There are two primary problems with your approach. The first is that ngRepeat uses an inherited scope, so primitive values (like strings and numbers) don't play nicely. You should pass arrays of objects to ngRepeat rather than arrays of primitives. Your second problem is the over-complicated way of of binding to an input. All you need is to this:

$scope.settings = {
  list: [
    { val: 'list item one'},
    { val: 'list item two'},
    { val: 'list item three'}
  ]
};

And then in your view:

<ul> 
  <li ng-repeat="item in settings.list">
    <input type="text" ng-model="item.val"></input>
    <a ng-click="remove($index)">delete</a>
  </li>
</ul>

Here's a revised plunker: http://plnkr.co/edit/ZGFjBnVSwM4hNSgVSOCW?p=preview .

Upvotes: 7

Related Questions