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
相关产品推荐
相关产品推荐

