【问题标题】:using ng-model within nested ng-repeat directives在嵌套的 ng-repeat 指令中使用 ng-model
【发布时间】:2013-04-12 14:28:05
【问题描述】:

我正在尝试在嵌套在 ng-repeat 指令中的 ng-repeat 指令“内”使用 ng-model。

以下 jsfiddle 演示了我的问题以及我解决该问题的两次尝试。

http://jsfiddle.net/rskLy/4/

我的控制器定义如下:

var mod = angular.module('TestApp', []);
mod.controller('TestCtrl', function ($scope) {        
var machine = {};
machine.noteMatrix = [
    [false, false, false],
    [false, true, false],
    [false, false, false]
];

$scope.machine = machine;

// ...
});

1.

<table>
    <thead>
        <tr>
            <th>--</th>
            <th ng-repeat="no in machine.noteMatrix[0]">{{$index+1}}</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="track in machine.noteMatrix">
            <td>--</td>                
            <td ng-repeat="step in track">                    
                <input type="checkbox" ng-model="track[$index]"> {{step}}
            </td>
        </tr>
    </tbody>
</table>

第一个示例/尝试更新控制器内的 machine.noteMatrix,但每次按下复选框时,angularjs 在 javascript 控制台中显示以下错误两次:

不允许在转发器中重复。中继器:步入轨道

有时它也会显示这个错误:

不允许在转发器中重复。中继器:没有在 machine.noteMatrix[0]

2.

<table>
    <thead>
        <tr>
            <th>--</th>
            <th ng-repeat="no in machine.noteMatrix[0]">{{$index+1}}</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="track in machine.noteMatrix">
            <td>--</td>                
            <td ng-repeat="step in track">                    
                <input type="checkbox" ng-model="step"> {{step}}
            </td>
        </tr>
    </tbody>
</table>

第二个示例/尝试从 noteMatrix 中正确读取数据,并且在选中/取消选中复选框时,javascript 控制台中不会显示任何错误。但是,更改它们的状态不会更新控制器中的 machine.noteMatrix(按“显示矩阵”按钮以查看 jsfiddle 中的矩阵)。

有人能解释一下吗? :)

【问题讨论】:

  • 使用 ng-repeat 时 $scope 属性会发生变化,因此请尝试使用 $parent.track[$index] 来访问外部范围。
  • 使用 $parent.track[$index] 而不是 track[$index] 会导致相同的 Duplicates in a repeater are not allowed. Repeater: step in track 错误
  • 在新的角度,有两个相同的项目是错误的github.com/angular/angular.js/blob/master/CHANGELOG.md
  • 好的。 angularjs 将它们报告为重复项,因为我重复原始类型并且这些是“按值传递”而不是引用。

标签: angularjs angularjs-ng-repeat


【解决方案1】:

这是 Angular 用户的常见问题。发生的事情是 ng-repeat 创建了它自己的范围,如果您将值类型数组传递给它(例如布尔数组),更新它们不会更新父范围。您需要将一组引用类型传递给 ng-repeat 并更新它们以使其持久化:

Here is a solution showing this based off of your fiddle

machine.noteMatrix = [
    [
        { value: false },
        { value: false }, 
        { value: false }
    ],
    [
        { value: false },
        { value: true }, 
        { value: false }
    ],
    [
        { value: false },
        { value: false }, 
        { value: false }
    ]
];

这很丑,我知道,但替代方案更丑。您需要做一些事情来管理您自己的循环并通过 $parent 或 $parent.$parent 对象引用这些值。我不推荐这个。

【讨论】:

  • 嗯,好的。我猜这是因为javascript“按值传递”所以原始类型被“复制”,而对象变量的值是对该对象的引用。那会计算吗?
  • 这是正确的。这与作用域原型继承父作用域的方式相结合。
  • 甜蜜。将此标记为正确答案。我的鼓机 UI 现在可以正常工作了。
【解决方案2】:

您的第一个解决方案似乎是正确的。

这似乎是一个错误,在 angularJS 的不稳定分支中引入(您使用的是不稳定的 1.1.4 - 稳定版本 1.0.6,按预期工作)

编辑:

原来这不是一个错误,而是一个新功能 - ngRepeat 指令现在允许定义一个跟踪函数(将模型的 id 与 DOM 元素相关联),并且不再允许这些跟踪变量重复。见the corresponding commitdocs for 1.1.4 on ngRepeatthe changelog

【讨论】:

  • 谢谢!回到 1.0.6 消除了 javascript 错误。我从 1.0.6 升级到 1.1.4,因为在 1.0.6 中使用第二种解决方案导致复选框不改变状态。升级到不稳定的 1.1.4 修复了该问题,但导致控制器中的 noteMatrix 未更新。 :(
【解决方案3】:

您无需更改模型或访问 $parent。缺少的是“按 $index 跟踪”:

    <tr ng-repeat="track in machine.noteMatrix">
        <td>--</td>                
        <td ng-repeat="step in track track by $index">                    
            <input type="checkbox" ng-model="track[$index]"> {{step}}
        </td>
    </tr>

Here it is in yr fiddle.

更多信息:Angular ng-repeat dupes

我不确定track by 在被问到问题时是否存在,所以当时其他答案可能是正确的,但在当前的 Angular 中,这是要走的路。

【讨论】:

  • 谢谢,对我来说缺少的部分是使用ng-model="track[$index]" 而不是ng-model="step"
猜你喜欢
  • 1970-01-01
  • 2015-10-12
  • 1970-01-01
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
  • 2014-01-09
  • 1970-01-01
  • 2017-09-08
相关资源
最近更新 更多