AngularJS ng-repeat重复项报错及单选按钮异常问题求助
第一个问题:重复项报错
你遇到的Duplicates in a repeater are not allowed错误,原因是track by document.Name无法区分重复项——要么你的documents数组里存在多个Name相同的文档,要么某个文档的Name字段是undefined,导致Angular找不到唯一的追踪键。
用track by $index确实能绕过重复项检查,但这只是临时方案,还引出了第二个更严重的问题。
第二个问题:点击单选按钮生成多个按钮
这个问题的核心是单选按钮的ng-model绑定错误:你把ng-model绑定到了数组project.documentConfig.documents上。当你点击单选按钮时,Angular会把这个数组直接替换成选中的document.Name字符串。比如选中名为"TestDoc"的文档,project.documentConfig.documents就变成了字符串"TestDoc",而ng-repeat会遍历字符串的每个字符,每个字符生成一个单选按钮,这就是你看到的“点击后出现一堆按钮”的原因。
修复方案
1. 修正ng-model绑定
给每个project新增一个专门存储选中文档的属性(比如selectedDocumentName),把单选按钮的ng-model绑定到这个属性上,而不是整个文档数组:
<td> <div ng-repeat="document in project.documentConfig.documents track by document.Name"> <label> <input type="radio" value="{{document.Name}}" ng-model="project.selectedDocumentName" /> <a ng-href="{{document.documentUrl}}" style="cursor: pointer;">{{ document.Name }}</a> </label> </div> </td>
2. 修正TrainProject调用
既然选中的文档名存在project.selectedDocumentName里,调用方法时传入这个属性即可:
<td><span class="train-project" ng-click="TrainProject(project.ProjectName, project.selectedDocumentName)" /></td>
3. 彻底解决重复项问题
如果你的document对象有唯一标识(比如documentId),优先用它作为追踪键,比document.Name或$index更可靠:
<div ng-repeat="document in project.documentConfig.documents track by document.documentId">
如果没有唯一ID,要么确保所有文档的Name不重复,要么继续用track by $index(但前提是已经修复了ng-model的问题)。
额外检查
确认你的接口返回的documents数组中,每个文档的Name字段都存在且不为空——如果有undefined的情况,track by document.Name依然会报错,这时候需要后端补充数据,或者改用其他追踪键。
内容的提问来源于stack exchange,提问作者Sam

