17

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

以下 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 中的矩阵)。

任何人都可以对此有所了解吗?:)

4

3 回答 3

15

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

这是一个基于您的小提琴的解决方案

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

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

于 2013-04-12T15:19:25.247 回答
3

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

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

编辑:

事实证明这不是一个错误,而是一个新功能 - ngRepeat 指令现在允许定义跟踪函数(将模型的 id 与 DOM 元素相关联),并且不再允许重复这些跟踪变量。请参阅相应的提交ngRepeat 上 1.1.4的文档和更改日志

于 2013-04-12T14:58:21.823 回答
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>

这是你的小提琴。

更多信息:Angular ng-repeat dupes

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

于 2014-07-02T19:42:38.893 回答