Angular中ng-repeat内动态命名textarea的表单验证异常问题
解决Angular ng-repeat中动态命名textarea的表单验证问题(controller as语法)
我之前也碰到过类似的坑,用controller as语法时,ng-repeat里动态命名的表单控件总是在form对象里显示最后一个$index的值,DOM里的名称却没问题,这其实是Angular处理动态控件名称和controller as作用域绑定的时机问题。
问题原因
当你直接用name="commentReply_{{$index}}"时,Angular在编译阶段会先尝试解析这个name属性,但此时ng-repeat的子作用域还没完全初始化,$index的插值会延迟到DOM渲染阶段完成。而controller as的main.adminArticleReplyForm是挂载在父作用域上的,控件注册到表单对象时,可能因为作用域解析时机的问题,所有控件都复用了最后一次循环的$index值,导致form对象里只显示最后一个控件名称。
解决方案
改用ng-attr-name来动态绑定控件名称,同时访问表单控件时使用数组语法,确保每个控件都正确注册到表单对象中:
<!-- 表单使用controller as语法绑定 --> <form name="main.adminArticleReplyForm"> <div ng-repeat="comment in main.comments track by $index"> <!-- 用ng-attr-name动态设置name属性,确保子作用域的$index被正确解析 --> <textarea ng-attr-name="commentReply_{{$index}}" ng-model="main.replies[$index]" required rows="3" ></textarea> <!-- 验证提示:用数组语法访问动态命名的控件 --> <div class="error-message" ng-show="main.adminArticleReplyForm['commentReply_' + $index].$invalid && main.adminArticleReplyForm['commentReply_' + $index].$touched"> 回复内容不能为空 </div> </div> </form>
关键要点
ng-attr-name的作用:它会在Angular的链接阶段(此时ng-repeat的子作用域已经完全初始化,$index值正确)动态设置textarea的name属性,确保每个控件的名称都是唯一且正确的,避免编译阶段的解析问题。- 数组语法访问控件:因为控件名称是动态生成的,不能用点语法(
main.adminArticleReplyForm.commentReply_0),必须用数组语法main.adminArticleReplyForm['commentReply_' + $index]来访问对应的表单控件状态。
这样修改后,你再查看{{main.adminArticleReplyForm}}时,就能看到每个commentReply_0、commentReply_1...等控件都正确注册在表单对象里,验证功能也能正常工作了。
内容的提问来源于stack exchange,提问作者Mat.Now
相关产品推荐
相关产品推荐

