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

时间:2022-08-22 09:18:31

I'm trying to use ng-model "within" a ng-repeat directive that is itself nested in a ng-repeat directive.

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

The following jsfiddle demonstrates my problem and my two attempts to solve it.

以下jsfiddle演示了我的问题,我的两个尝试解决它。

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

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

My Controller is defined as follows:

我的控制器定义如下:

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.

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>

The first example/attempt updates the machine.noteMatrix inside the controller, but everytime a checkbox is pressed, angularjs displays the following error twice in the javascript console:

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

Duplicates in a repeater are not allowed. Repeater: step in track

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

and sometimes it will also display this error:

有时它也会显示此错误:

Duplicates in a repeater are not allowed. Repeater: no in machine.noteMatrix[0]

不允许在转发器中重复。中继器:机器中没有。注意矩阵[0]

2.

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>

The second example/attempt reads the data correctly from the noteMatrix and no errors are displayed in the javascript console when checking/unchecking the checkboxes. However changing their states is not updating the machine.noteMatrix in the controller (press the "Show Matrix" button to see the matrix in the jsfiddle).

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

Can anyone shed a light on this? :)

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

3 个解决方案

#1


14  

This is a common issue for people in Angular. What's happening is ng-repeat creates it's own scope, and if you pass an array of value types into it (such as an array of booleans), updating them will not update the parent scope. You need to pass an array of reference types to the ng-repeat and update those in order for it to persist:

对于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 }
    ]
];

It's ugly, I know, but the alternative is uglier. You'd need to do something to manage your own loop and reference the values via the $parent or $parent.$parent object. I don't recommend this.

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

#2


3  

Your first solution seems to be correct.

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

This appears to be a bug, introduced in the unstable branch of angularJS (you are using 1.1.4, which is unstable - the stable version, 1.0.6, works as expected)

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

EDIT:

编辑:

Turns out this isn't a bug, but a new feature - the ngRepeat directive now allows for a tracking function to be defined (associating the model's id with the DOM element), and no longer allows for these tracking variables to be repeated. See the corresponding commit, the docs for 1.1.4 on ngRepeat and the changelog

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

#3


3  

You don't need to alter your model or access the $parent. What's missing is "track by $index":

您无需更改模型或访问$ 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.

这是小提琴。

More information: Angular ng-repeat dupes

更多信息:Angular ng-repeat dupes

I'm not sure if track by existed yet when the question was asked, so the other answers may have been correct at the time, but in current Angular this is the way to go.

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

#1


14  

This is a common issue for people in Angular. What's happening is ng-repeat creates it's own scope, and if you pass an array of value types into it (such as an array of booleans), updating them will not update the parent scope. You need to pass an array of reference types to the ng-repeat and update those in order for it to persist:

对于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 }
    ]
];

It's ugly, I know, but the alternative is uglier. You'd need to do something to manage your own loop and reference the values via the $parent or $parent.$parent object. I don't recommend this.

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

#2


3  

Your first solution seems to be correct.

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

This appears to be a bug, introduced in the unstable branch of angularJS (you are using 1.1.4, which is unstable - the stable version, 1.0.6, works as expected)

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

EDIT:

编辑:

Turns out this isn't a bug, but a new feature - the ngRepeat directive now allows for a tracking function to be defined (associating the model's id with the DOM element), and no longer allows for these tracking variables to be repeated. See the corresponding commit, the docs for 1.1.4 on ngRepeat and the changelog

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

#3


3  

You don't need to alter your model or access the $parent. What's missing is "track by $index":

您无需更改模型或访问$ 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.

这是小提琴。

More information: Angular ng-repeat dupes

更多信息:Angular ng-repeat dupes

I'm not sure if track by existed yet when the question was asked, so the other answers may have been correct at the time, but in current Angular this is the way to go.

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