在嵌套的ng-repeat指令中使用ng-model

时间:2013-04-12 14:28:05

标签: angularjs angularjs-ng-repeat

我正在尝试在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控制台中显示以下错误两次:

  

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

有时它也会显示此错误:

  

不允许在转发器中重复。 Repeater:no in 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中的矩阵)。

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

3 个答案:

答案 0 :(得分:14)

对于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对象引用这些值。我不推荐这个。

答案 1 :(得分:3)

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

<击>

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

修改

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

答案 2 :(得分:3)

您不需要更改模型或访问$ parent。缺少的是&#34;跟踪$ index&#34;:

    <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中,这是要走的路。