Angular表单添加数组元素时丢失已填数据问题求助
问题描述
点击「aggiungi gruppo」按钮会向*ngFor指令循环遍历的数组中添加元素,但将所有HTML内容用<form>标签包裹后,每次添加新元素,之前填写的表单值都会丢失;不使用<form>标签则一切正常。
HTML代码
<h1>Gestione esercizi</h1> <!-- <form #EsercizioForm="ngForm" style="display: flex;flex-direction: column;" (submit)="OnSubmit(EsercizioForm)"> --> <mat-form-field > <mat-label>Nome esercizio</mat-label> <input matInput placeholder="Squat" required name="nomeEsercizio" ngModel> </mat-form-field> <mat-form-field class="example-full-width"> <mat-label>Descrizione</mat-label> <textarea matInput placeholder="Es. accosciata" name="descrizioneEsercizio" ngModel></textarea> </mat-form-field> <div style="display: flex;flex-direction: column;"> <mat-form-field *ngFor="let cg of elencoGruppiMuscolari;let i = index;"> <mat-select placeholder="gruppo muscolare" name="nome" [(ngModel)]="elencoGruppiMuscolari[i].nome" > <mat-option *ngFor="let g of gruppiMuscolari" [value]="g.nome"> {{g.nome}} </mat-option> </mat-select> </mat-form-field> </div> <div><span>Aggiungi un gruppo</span><button type="button" mat-icon-button (click)="OnAddClasseGruppoMuscolare()"> <mat-icon>add</mat-icon> </button></div> <button mat-button color="primary" type="button" (click)="OnSubmit(null)">Crea</button> <!-- </form> -->
TypeScript代码
import { Component, OnInit } from '@angular/core'; import { NgForm } from '@angular/forms'; import { Esercizio } from 'src/app/modelli/esercizio'; import { gruppoMuscolare } from 'src/app/modelli/gruppoMuscolare'; @Component({ selector: 'app-esercizio', templateUrl: './esercizio.component.html', styleUrls: ['./esercizio.component.css'] }) export class EsercizioComponent implements OnInit{ private esercizio:Esercizio // esercizio.gruppiMuscolari =gruppoMuscolare[]; // esercizio.elencoGruppiMuscolari : gruppoMuscolare[] elencoGruppiMuscolari = [{nome:''}]; gruppiMuscolari = [ {nome:'bicipiti'}, {nome:'tricipiti'}, {nome:'petto'}, {nome:'dorsali'}, {nome:'trapezio'}, {nome:'deltoide'}, {nome:'quadricipiti'}, {nome:'ischiodurali'}, {nome:'polpacci'}, {nome:'lombari'}, {nome:'glutei'}, ]; ngOnInit(): void { } constructor(){} OnAddClasseGruppoMuscolare() { //here's where i add the new element this.elencoGruppiMuscolari.push({nome:''}); // } OnSubmit(ngForm:NgForm) { this.esercizio.nome= ngForm.value.nome; this.esercizio.descrizione= ngForm.value.descrizione; this.esercizio.gruppiMuscolari=this.elencoGruppiMuscolari; } }
解决方案
问题核心是模板驱动表单中动态生成的控件name属性重复,Angular会基于name属性注册表单控件,重复的name会导致表单状态混乱,添加新元素触发DOM重渲染时丢失输入值。
具体修复步骤:
给动态控件设置唯一
name属性
给mat-select的name加上索引后缀,确保每个控件在表单中唯一:<mat-select placeholder="gruppo muscolare" name="gruppoMuscolare-{{i}}" [(ngModel)]="cg.nome">简化
ngModel绑定
直接绑定到*ngFor循环的cg变量,无需通过数组索引,避免索引追踪问题:<mat-form-field *ngFor="let cg of elencoGruppiMuscolari;let i = index;"> <mat-select placeholder="gruppo muscolare" name="gruppoMuscolare-{{i}}" [(ngModel)]="cg.nome"> <mat-option *ngFor="let g of gruppiMuscolari" [value]="g.nome"> {{g.nome}} </mat-option> </mat-select> </mat-form-field>初始化
esercizio对象
原代码中esercizio未初始化,提交时会报错,需在ngOnInit中初始化:ngOnInit(): void { this.esercizio = new Esercizio(); // 假设Esercizio类有默认构造函数 }修正表单提交逻辑
匹配表单字段的真实name值,避免取值错误:OnSubmit(ngForm:NgForm) { this.esercizio.nome= ngForm.value.nomeEsercizio; this.esercizio.descrizione= ngForm.value.descrizioneEsercizio; this.esercizio.gruppiMuscolari=this.elencoGruppiMuscolari; }
完成以上修改后,重新启用<form>标签,添加新元素时就不会丢失之前的表单值了。
内容的提问来源于stack exchange,提问作者Lorenzo
相关产品推荐
相关产品推荐

