You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>

关键要点

  1. ng-attr-name的作用:它会在Angular的链接阶段(此时ng-repeat的子作用域已经完全初始化,$index值正确)动态设置textarea的name属性,确保每个控件的名称都是唯一且正确的,避免编译阶段的解析问题。
  2. 数组语法访问控件:因为控件名称是动态生成的,不能用点语法(main.adminArticleReplyForm.commentReply_0),必须用数组语法main.adminArticleReplyForm['commentReply_' + $index]来访问对应的表单控件状态。

这样修改后,你再查看{{main.adminArticleReplyForm}}时,就能看到每个commentReply_0、commentReply_1...等控件都正确注册在表单对象里,验证功能也能正常工作了。

内容的提问来源于stack exchange,提问作者Mat.Now

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:04:47