使用ngRepeat =>将输入绑定到基元数组不可编辑的投入

时间:2013-03-18 22:40:19

标签: angularjs angularjs-scope angularjs-ng-repeat

这是我问题的demo

$scope.myNumbers = [10, 20, 30];

<div ng-repeat="num in myNumbers">
    <input type="text" ng-model="num">
    <div>current scope: {{num}}</div>
</div>

任何人都可以向我解释为什么输入不可编辑/只读?如果按照设计,背后的理由是什么?

更新2/20/2014

对于v1.2.0 + Demo,这似乎不再是问题。但请记住,尽管现在可以使用较新的angularJS版本编辑用户控件,但它是 子范围 中的num属性,而不是父级范围,得到修改。换句话说,修改用户控件中的值不会影响myNumbers数组。

5 个答案:

答案 0 :(得分:67)

  

任何人都可以向我解释为什么输入不可编辑/只读?如果按照设计,背后的理由是什么?

这是设计上的,as of Angular 1.0.3。当你“直接绑定到每个ng-repeat项目”时,Artem有very good explanation 1.0.3+如何工作 - 即

<div ng-repeat="num in myNumbers">
  <input type="text" ng-model="num">

当您的页面最初呈现时,这里是您的示波器的图片(我删除了其中一个数组元素,因此图片将有更少的框):

enter image description here (点击放大)

虚线显示原型范围继承 灰线显示子→父关系(即$parent引用的内容) 布朗线显示$$ nextSibling 灰色框是原始值。 蓝框是数组。紫色是物体。

请注意,我在评论中引用的SO答案是在1.0.3出现之前编写的。在1.0.3之前,当您在文本框中键入时,ngRepeat子范围中的num值实际上会发生变化。 (这些值在父作用域中不可见。)从1.0.3开始,ngRepeat现在用父/ MainCtrl作用域num数组中的(未更改)值替换ngRepeat作用域myNumbers值。消化周期。这实际上使输入无法实现。

修复方法是在MainCtrl中使用一组对象:

$scope.myNumbers = [ {value: 10}, {value: 20} ];

然后绑定到ngRepeat中对象的value属性:

<div ng-repeat="num in myNumbers">
  <input type="text" ng-model="num.value">
  <div>current scope: {{num.value}}</div>

答案 1 :(得分:33)

现在,更新版的AngularJS解决了这个问题,track by功能允许转发器超过基元:

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

每次击键后页面都不会重新绘制,这样可以解决失去焦点的问题。 AngularJS官方文档对此非常模糊和混淆。

答案 2 :(得分:9)

似乎Angular无法写入以这种方式定义的模型。使用对初始$ scope属性的引用让它以正确的方式绑定值:

<div ng-repeat="num in myNumbers">
  <input type="text" ng-model="myNumbers[$index]">
</div>

答案 3 :(得分:9)

ngRepeat使用引用到源数组。由于integer (Number in js)类型,而不是引用类型,因此无法通过javascript中的引用传递。此更改不会传播。

这是一个演示:

   var x = 10;
   var ox = {value:10};

   var y = x;
   var oy = ox;

   y = 15
   oy.value = 15;

xox的价值是什么?

>> x = 10;
>> y = 15;
>> ox = {value:15};
>> oy = {value:15};

所有javascript对象都通过引用传递,所有基元都通过值[“string”,“number”等]传递。

工作人员http://plnkr.co/edit/7uG2IvAdC2sAEHbdHG58

答案 4 :(得分:9)

我有类似的问题(还需要'添加'和'删除'功能),并解决了这样的问题:

$scope.topics = [''];
$scope.removeTopic = function(i) {
   $scope.topics.splice(i, 1); 
}

<div ng-repeat="s in topics track by $index">
    <input ng-model="$parent.topics[$index]" type="text">
    <a ng-click="removeTopic($index)">Remove</a>
</div>

<a ng-click="topics.push('new topic')">Add</a>