什么是数据绑定许多输入的angularjs方法?

rce*_*ell 31 javascript angularjs

我正在学习angularjs,我希望能够让用户输入许多输入.输入这些输入后,list数组元素应相应更改.我想尝试使用ngRepeat指令,但我读到了,因为它创建了一个新的范围,我无法数据绑定:

<div ng-repeat="item in list">
    <label>Input {{$index+1}}:</label>
    <input ng-model="item" type="text"/>
</div>
Run Code Online (Sandbox Code Playgroud)

我想知道我是否应该使用自定义指令来执行此操作或以不同方式处理它.

Mar*_*cok 87

数据绑定到基本"项"的原因不起作用的原因是ng-repeat为每个项创建子范围的方式.对于每个项目,ng-repeat使新的子范围原型继承自父范围(请参见下图中的虚线),然后将项目的值分配给子范围上的新属性(下图中的红色项目).新属性的名称是循环变量的名称.来自ng-repeat源代码:

childScope = scope.$new();
...
childScope[valueIdent] = value;
Run Code Online (Sandbox Code Playgroud)

如果item是基元,则新的子范围属性实际上被分配了基元值的副本.父作用域不显示此子作用域属性,并且对输入字段所做的更改将存储在此子作用域属性中.例如,假设我们在父范围内

$scope.list = [ 'value 1', 'value 2', 'value 3' ];
Run Code Online (Sandbox Code Playgroud)

在HTML中:

<div ng-repeat="item in list">
Run Code Online (Sandbox Code Playgroud)

然后,第一个子范围将具有以下item属性,具有原始值(value 1):

item: "value 1"
Run Code Online (Sandbox Code Playgroud)

ng-repeat with primitives

由于ng-model数据绑定,您对表单输入字段所做的更改将存储在该子范围属性中.

您可以通过将子范围记录到控制台来验证这一点.在ng-repeat中添加到HTML:

<a ng-click="showScope($event)">show scope</a>
Run Code Online (Sandbox Code Playgroud)

添加到您的控制器:

$scope.showScope = function(e) {
    console.log(angular.element(e.srcElement).scope());
}
Run Code Online (Sandbox Code Playgroud)


使用@ Gloopy的方法,每个子作用域仍然获得一个新的"item"属性,但由于list现在是一个对象数组,因此childScope[valueIdent] = value;将item属性的值设置为对其中一个数组对象(不是副本)的引用.

ng-repeat with objects

使用showScope()技术,您将看到子范围item属性的值引用其中一个数组对象 - 它不再是原始值.

另请参阅不绑定到ng-repeat子范围中的基元以及
AngularJS中范围原型/原型继承的细微差别是什么?(其中包含使用ng-repeat时范围的图片).

  • 图表太棒了! (8认同)
  • @abbood,[tag:GraphViz]. (8认同)

Glo*_*opy 37

如果你list是一个对象数组(而不是一个基元数组),你会有更好的运气.即使使用ng-repeat以下命令创建新范围,这也可以正常工作:

<div ng-repeat="item in list">
    <label>Input {{$index+1}}:</label>
    <input ng-model="item.value" type="text"/>
</div>
Run Code Online (Sandbox Code Playgroud)

控制器:

function TestController($scope) {
    $scope.list = [ { value: 'value 1' }, { value: 'value 2' }, { value: 'value 3' } ];
}?
Run Code Online (Sandbox Code Playgroud)

这个小提琴为例.

另一方面,如果您尝试绑定到字符串数组,新范围将导致问题,因为您正在修改的值将不会绑定到原始数​​组字符串基元(如此小提琴示例中所示).