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

Angular中如何独立控制循环生成的表单提交按钮禁用/启用

问题描述

在Angular应用中使用*ngFor生成多个表单时,修改单个输入框会导致所有提交按钮同步禁用/启用。希望仅当对应表单的输入框变化时,控制该表单的提交按钮状态,而非全局联动。当前HTML代码如下:

<mat-card *ngIf="myText">
  <h1 mat-header class="center">My texts</h1>
  <mat-card-content>
    <div *ngFor="let item of myText">
      <h3 mat-subheader class="center">myText {{ item.index + 1 }}</h3>
      <p class="message">{{ item.textmessage }}</p>
      <form [formGroup]="myTextForm" class="myText-form" (ngSubmit)="sendPrompt(item.index)">
        <mat-form-field class="full-width" *ngIf="!error">
          <mat-label>Respond to text</mat-label>
          <textarea
            matInput
            cdkTextareaAutosize
            cdkAutosizeMinRows="3"
            cdkAutosizeMaxRows="20"
            formControlName="prompt"
            required="true"
          ></textarea>
        </mat-form-field>
        <p>
          <button mat-raised-button class="btn" color="primary" [disabled]="myTextForm.invalid" type="submit">
            Respond
          </button>
          <button
            mat-raised-button
            color="accent"
            [cdkCopyToClipboard]="item.textmessage"
          >
            Copy to clipboard
          </button>
        </p>
      </form>
      <mat-divider *ngIf="item.index + 1 < myText.length"></mat-divider>
    </div>
  </mat-card-content>
</mat-card>
解决方案

问题核心是所有表单共用了同一个myTextForm表单组,导致单个输入框的状态变化会影响所有按钮。需要为每个列表项创建独立的表单组:

1. 组件类修改

将单个FormGroup替换为FormGroup数组,初始化数据时为每个项生成对应的表单组:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-your-component',
  templateUrl: './your-component.component.html',
  styleUrls: ['./your-component.component.css']
})
export class YourComponent implements OnInit {
  myText: any[] = [];
  myTextForms: FormGroup[] = [];

  constructor(private fb: FormBuilder) {}

  ngOnInit(): void {
    // 假设此处是初始化myText数据的逻辑
    this.myText = [/* 你的数据内容 */];
    // 为每个数据项创建独立表单组
    this.myText.forEach(() => {
      this.myTextForms.push(this.fb.group({
        prompt: ['', Validators.required]
      }));
    });
  }

  sendPrompt(index: number): void {
    // 根据索引获取对应表单的值进行提交逻辑处理
    const formData = this.myTextForms[index].value;
    // 后续提交操作
  }
}

2. 模板代码修改

在*ngFor中获取当前项的索引,绑定对应索引的表单组,并通过该表单组判断按钮禁用状态:

<mat-card *ngIf="myText">
  <h1 mat-header class="center">My texts</h1>
  <mat-card-content>
    <div *ngFor="let item of myText; let i = index">
      <h3 mat-subheader class="center">myText {{ item.index + 1 }}</h3>
      <p class="message">{{ item.textmessage }}</p>
      <form [formGroup]="myTextForms[i]" class="myText-form" (ngSubmit)="sendPrompt(i)">
        <mat-form-field class="full-width" *ngIf="!error">
          <mat-label>Respond to text</mat-label>
          <textarea
            matInput
            cdkTextareaAutosize
            cdkAutosizeMinRows="3"
            cdkAutosizeMaxRows="20"
            formControlName="prompt"
            required="true"
          ></textarea>
        </mat-form-field>
        <p>
          <button mat-raised-button class="btn" color="primary" [disabled]="myTextForms[i].invalid" type="submit">
            Respond
          </button>
          <button
            mat-raised-button
            color="accent"
            [cdkCopyToClipboard]="item.textmessage"
          >
            Copy to clipboard
          </button>
        </p>
      </form>
      <mat-divider *ngIf="item.index + 1 < myText.length"></mat-divider>
    </div>
  </mat-card-content>
</mat-card>

修改后每个表单拥有独立的状态,输入框的变化只会影响对应表单的提交按钮,不会再出现全局联动的问题。

内容的提问来源于stack exchange,提问作者naitunix

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 04:32:40