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

I am trying to allow the user to edit a list of items by using ngRepeat and ngModel. (See this fiddle.) However, both approaches I've tried lead to bizarre behavior: one doesn't update the model, and the other blurs the form on each keydown.

Am I doing something wrong here? Is this not a supported use case?

Here is the code from the fiddle, copied for convenience:

<html ng-app>
<head>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/css/bootstrap-combined.min.css" rel="stylesheet">
</head>
<body ng-init="names = ['Sam', 'Harry', 'Sally']">
<h1>Fun with Fields and ngModel</h1>
<p>names: {{names}}</p>
<h3>Binding to each element directly:</h3>
<div ng-repeat="name in names">
Value: {{name}}
<input ng-model="name">
</div>
<p class="muted">The binding does not appear to be working: the value in the model is not changed.</p>
<h3>Indexing into the array:</h3>
<div ng-repeat="name in names">
Value: {{names[$index]}}
<input ng-model="names[$index]">
</div>
<p class="muted">Type one character, and the input field loses focus. However, the binding appears to be working correctly.</p>
</body>
</html>

162010 次浏览

这似乎是一个有约束力的问题。

建议是 不要和原语绑定

您的 ngRepeat正在对集合中的字符串进行迭代,而它应该在对象上进行迭代

<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>

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

当需要了解 显微镜重复模特如何与 模型控制器一起工作时,你就陷入了困境。还可以尝试使用1.0.3版本。你的例子会有点不同。

您可以简单地使用 jm-提供的解决方案

但如果你想更深入地处理这种情况,你必须明白:

  • how AngularJS works;
  • 作用域具有层次结构;
  • 重复为每个元素创建新的作用域;
  • 带有附加信息(hashKey)的项的构建缓存; 对于每个新项(不在缓存中)的每个 watch 调用,ngRepeat 构造新范围、 DOM 元素等。更详细的描述.
  • 从1.0.3 ngModelController 重新呈现具有实际模型值的输入。

你的例子“直接绑定到每个元素”是如何在 AngularJS 1.0中工作的。3:

  • 输入字母 'f';
  • ngModelController项目范围更改模型(名称数组未更改) = > name == 'Samf'names == ['Sam', 'Harry', 'Sally'];
  • $digest循环启动;
  • ngRepeat将项目范围('Samf')中的模型值替换为未更改名称数组('Sam')中的值;
  • ngModelController使用实际的模型值('Sam')重新呈现输入。

你的例子“索引到数组”是如何工作的:

  • 输入字母 'f';
  • ngModelController changes item in names array => `names == ['Samf', 'Harry', 'Sally'];
  • $消化循环启动;
  • ngRepeat can't find 'Samf' in cache;
  • ngRepeat创建新的范围,添加新的 div 元素和新的输入(这就是为什么输入字段失去焦点——旧的 div 和旧的输入被新的 div 和新的输入替换) ;
  • 呈现新 DOM 元素的新值。

此外,还可以尝试使用 AngularJS Batarang,查看如何通过输入更改 div 作用域的 $id。

我刚刚更新 AngularJs 到1.1.2,没有问题。我想这个错误是固定的。

Http://ci.angularjs.org/job/angular.js-pete/57/artifact/build/angular.js

我尝试了上面的解决方案,它非常有效。谢谢!

Http://jsfiddle.net/leighboone/wn9ym/7/

以下是我对此的看法:

var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.models = [{
name: 'Device1',
checked: true
}, {
name: 'Device1',
checked: true
}, {
name: 'Device1',
checked: true
}];


}

和我的 HTML

<div ng-app="myApp">
<div ng-controller="MyCtrl">
<h1>Fun with Fields and ngModel</h1>
<p>names: \{\{models}}</p>
<table class="table table-striped">
<thead>
<tr>
<th></th>
<th>Feature 1</td>
<th>Feature 2</th>
<th>Feature 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Device</td>
<td ng-repeat="modelCheck in models" class=""> <span>
\{\{modelCheck.checked}}
</span>


</td>
</tr>
<tr>
<td>
<label class="control-label">Which devices?</label>
</td>
<td ng-repeat="model in models">\{\{model.name}}
<input type="checkbox" class="checkbox inline" ng-model="model.checked" />
</td>
</tr>
</tbody>
</table>
</div>
</div>

使用角度最新版本(1.2.1)和轨道由 $index。这个问题是固定的

Http://jsfiddle.net/rnw3u/53/

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

如果你不需要每次按键都更新模型,只需要绑定到 name,然后在模糊事件中更新数组项:

<div ng-repeat="name in names">
Value: \{\{name}}
<input ng-model="name" ng-blur="names[$index] = name" />
</div>

how do something like:

<select ng-model="myModel($index+1)">

And in my inspector element be:

<select ng-model="myModel1">
...
<select ng-model="myModel2">

问题似乎在于 ng-model如何与 input一起工作,并覆盖 name对象,使其在 ng-repeat中丢失。

作为解决方案,可以使用以下代码:

<div ng-repeat="name in names">
Value: \{\{name}}
<input ng-model="names[$index]">
</div>

希望能有帮助