数据绑定的input是什么?
我正在学习angularjs,我希望能够让用户input很多input。 当input这些input时, list
数组元素应该相应地改变。 我想尝试使用ngRepeat指令,但我读到,因为它创build一个新的范围,我不能databind:
<div ng-repeat="item in list"> <label>Input {{$index+1}}:</label> <input ng-model="item" type="text"/> </div>
我想知道如果我应该使用自定义指令来做到这一点或以不同的方式。
如果你的list
是一个对象数组(而不是一个基元数组),你会有更好的运气。 即使用ng-repeat
创build一个新的作用域,这也可以正常工作:
<div ng-repeat="item in list"> <label>Input {{$index+1}}:</label> <input ng-model="item.value" type="text"/> </div>
与一个控制器:
function TestController($scope) { $scope.list = [ { value: 'value 1' }, { value: 'value 2' }, { value: 'value 3' } ]; }
以这个小提琴为例。
另一方面,如果你试图绑定到一个string数组,那么新的作用域将会引起一个问题,因为你正在修改的值不会绑定到原始数组string基元(就像在这个小提琴的例子中)。
数据绑定到原始“项目”不起作用的原因是ng-repeat为每个项目创build子范围的方式。 对于每个项目,ng-repeat都有从父范围原型inheritance的新子范围(参见下图中的虚线), 然后将项目的值分配给子范围上的新属性(下图中的红色项目)。 新属性的名称是循环variables的名称。 从ng-repeat源代码 :
childScope = scope.$new(); ... childScope[valueIdent] = value;
如果item是一个基元,那么新的子范围属性本质上被分配了一个基元值的副本。 此子范围属性对父范围不可见,并且您对input字段所做的更改存储在此子范围属性中。 例如,假设我们在父范围内
$scope.list = [ 'value 1', 'value 2', 'value 3' ];
而在HTML中:
<div ng-repeat="item in list">
然后,第一个子作用域将具有以下item
属性,具有原始值( value 1
):
item: "value 1"
由于ng-model数据绑定,您对表单的input字段所做的更改将存储在该子范围属性中。
您可以通过将子作用域logging到控制台来validation。 在ng-repeat中join你的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;
导致项目属性的值被设置为对数组对象之一(不是副本)的引用。
使用showScope()技术,您将看到子范围item
属性的值引用了其中一个数组对象 – 它不再是原始值。
另请参阅不要绑定到ng-repeat子范围和中的基元
AngularJS中范围原型/原型inheritance的细微差别是什么? (其中包含使用ng-repeat时的范围图片)。
我发现了一个有趣的方法,它允许我处理一系列基元。
我正在使用AngularJS 1.2.1,这是我可以使这个工作的唯一版本。
HTML:
<div ng-repeat="item in list"> <label>Input {{$index+1}}:</label> <input ng-model="item" type="text" ng-blur="editItem($index, item)"/> </div>
JavaScript的:
$scope.editItem = function(idx, eItem) { $scope.list[idx] = eItem; };
链接: http : //jsfiddle.net/bxD2P/10/ (感谢Gloopy为首发小提琴)
我确信在这个工作方式中有很多简单的方法来挖洞,我很乐意听到他们的声音。 这将允许我支撑我的代码。
这是一个办法。 我用textareas和一个不同的结构,我的中继器,但主要的概念是:
- 根据索引显示一个简单的值。 (不受限制)
- 模糊更新模型
- 在模型更新重新呈现
它本质上是假装绑定。
工作小提琴 – http://jsfiddle.net/VvnWY/4/
html:
<script type="text/ng-template" id="textareas.html"> <textarea ng-if="strings" ng-repeat="str in strings" ng-blur="blur( $event, $index )">{{strings[$index]}}</textarea> </script> <div ng-controller="MyCtrl"> Here's a few strings: <br /> <div ng-repeat="str in strings">{{strings[$index]}}</div> Here's the strings as editable (twice so that you can see the updates from a model change): <br /> <form-textareas strings="strings"></form-textareas> <form-textareas strings="strings"></form-textareas> </div>
JS:
var myApp = angular.module('myApp',[]); angular.module('myApp', []) .controller('MyCtrl', ['$scope', function($scope) { $scope.strings = [ "foo", "bar", "cow" ]; }]) .directive('formTextareas', function() { return { restrict: "E", scope: { strings: '=' }, templateUrl: "textareas.html", link: function( $scope ){ $scope.blur = function( $event, $index ){ $scope.strings[ $index ] = $event.currentTarget.value; }; } }; }) ;