Angular.JS: why can't the inputs be edited?

All we need is an easy explanation of the problem, so here it is.

This is a strange problem. The code is simple:

HTML code:

<body ng-controller="MainCtrl">
  <ul ng-repeat="name in names">
    <input type="text" ng-model="name" />
  </ul>
</body>

Angular code:

app.controller('MainCtrl', function($scope) {
    $scope.names = ["aaa","bbb","ccc"];
});

The live demo url is: http://plnkr.co/edit/2QFgRooeFUTgJOo223k9?p=preview

I do not understand why the input controls can not be edited, I can’t type new characters or delete characters.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

This is a common issue due to scope inheritance . Each of your names is a primitive so ng-repeat makes it’s own scope item that is not connected to original, however if each names is an object ng-repeat scope item will be a reference to original object

 [{name:"aaa"},{name:"bbb"},{name:"ccc"}];

Always use a dot in ng-model is a helpful rule of thumb

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

Working Plunker

Read this article on angular github wiki for detailed explanaton:

https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance

Method 2

Angular ‘fixed’ this in 1.1 with the track by $index. No need to change your model.

<div ng-repeat="item in names track by $index">
    <input type="text" ng-model="names[$index]" />
</div>

Plunker here

Method 3

Late answer, but you should also be careful of typos, that angular will not warn you about:

<div ng-repeat="item in names track by $index" ng=if="names[$index] = 'John'">
    <input type="text" ng-model="names[$index]" />
</div>

Note the single equals in the ng-if, that will not cause a warning or error, but the text will also be read only. Quite a hard one to spot if you are reading quickly.

It of course should be:

<div ng-repeat="item in names track by $index" ng-if="names[$index] == 'John'">
    <input type="text" ng-model="names[$index]" />
</div>

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply