数据绑定到原始“项目”不起作用的原因是 ng-repeat 为每个项目创建子范围的方式。对于每个项目,ng-repeat 都有新的子范围原型继承自父范围(见下图中的虚线),然后它将项目的值分配给子范围上的新属性(下图中的红色项目)。新属性的名称是循环变量的名称。从ng-repeat 源代码:
childScope = scope.$new();
...
childScope[valueIdent] = value;
如果 item 是原语,则新的子范围属性本质上被分配了原语值的副本。此子范围属性对父范围不可见,您对输入字段所做的更改存储在此子范围属性中。例如,假设我们在父范围内
$scope.list = [ 'value 1', 'value 2', 'value 3' ];
在 HTML 中:
<div ng-repeat="item in list">
然后,第一个子作用域将具有以下item
属性,具有原始值 ( value 1
):
item: "value 1"

由于 ng-model 数据绑定,您对表单输入字段所做的更改存储在该子范围属性中。
您可以通过将子范围记录到控制台来验证这一点。在 ng-repeat 中添加到您的 HTML:
<a ng-click="showScope($event)">show scope</a>
添加到您的控制器:
$scope.showScope = function(e) {
console.log(angular.element(e.srcElement).scope());
}
使用@Gloopy 的方法,每个子作用域仍然获得一个新的“item”属性,但是因为 list 现在是一个对象数组,
childScope[valueIdent] = value;
导致 item 属性的值被设置为对其中一个数组对象的引用(而不是副本)。

使用 showScope() 技术,您将看到子范围item
属性的值引用了数组对象之一——它不再是原始值。
另请参阅不要绑定到 ng-repeat 子范围中的原语和
AngularJS 中范围原型/原型继承的细微差别是什么?(其中包含使用 ng-repeat 时范围的图片)。