angular - 重置 Angular Reactive FormArray 值
问题描述
我遇到了 Angular 响应式表单的一个奇怪错误。我正在使用 FormArray 创建一个可以添加或删除字段的表单。我还希望能够重置表单,使表单输入的值和数量恢复到原始数量。我目前能够实例化表单,添加字段并删除它们,但是当我按下重置时,我创建的函数首先清空 FormArray,然后使用与最初设置表单相同的过程重新创建字段, 值不能正确显示。我不确定为什么会发生这种情况,也许与用于在 html 中绑定表单的 formControlNames 有关?
有谁知道导致问题的原因或重置表单值的正确方法是什么?
我在这里创建了一个堆栈闪电战:https ://stackblitz.com/edit/angular-reactive-formarray-bug
这是我的组件代码。
import {
Component, ElementRef
} from '@angular/core';
import { FormBuilder, FormGroup, FormArray, FormControl } from '@angular/forms';
import { ContentTemplate, ContentTemplateEntry, NewContentEntry } from './models';
import {Observable, Subscription, of} from 'rxjs';
import data from './template-data.json';
@Component({
selector: 'material-app',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent {
public templateForm: FormGroup;
public contentTemplate$: Observable<ContentTemplate>;
public activeTemplate: ContentTemplate;
public templateSub: Subscription;
public entries: ContentTemplateEntry[];
get templateEntries(): FormArray {
return <FormArray>this.templateForm.get('entries');
}
constructor(
private fb: FormBuilder
) {
this.contentTemplate$ = of(data)
}
ngOnInit(): void {
this.templateSub = this.contentTemplate$.subscribe((template: ContentTemplate) => {
this.activeTemplate = {...template};
this.entries = [...template.entries];
this.templateForm = this.fb.group({
entries: this.fb.array([])
});
this._processEntries(this.entries);
});
}
ngOnDestroy(): void {
this.templateSub.unsubscribe();
}
private _buildEntry(entry: ContentTemplateEntry) {
const g = this.fb.group({
id: {value: entry.id},
title: {value: entry.title, disabled: entry.isRequired},
orderNumber: {value: entry.orderNumber},
type: {value: entry.type}
});
return g;
}
private _processEntries(entries: ContentTemplateEntry[]) {
entries.forEach((e, i) => {
this.templateEntries.push(this._buildEntry(e));
});
}
private _getOrderNumber(): number {
return this.templateEntries.length + 1;
}
private _removeItemsFromEntries(): void {
while (this.templateEntries.length > 0) {
this.templateEntries.removeAt(0);
}
}
// reinstantiate using the same approach as before
public resetForm() {
this._removeItemsFromEntries();
this._processEntries(this.entries);
}
public removeEntry(id: number) {
this.templateEntries.removeAt(id);
}
public addEntry() {
this.templateEntries.push(
this._buildEntry(new NewContentEntry({
orderNumber: this._getOrderNumber()
}))
);
}
public save() {
console.log('save triggered');
}
}
解决方案
您的错误是由type="reset"
重置按钮引起的。删除此属性或替换为type="button"
将解决问题。
重置表单的正确方法是调用属性reset()
上的方法。templateForm
重置 FormGroup,将所有后代标记为原始且未触及,并将所有后代的值设为 null。
推荐阅读
- ios - iOS - 保存到日志文件并稍后提取
- c++ - 如何使用 Swift 包管理器创建 C++ 包?
- c# - 检测按下键盘 Tab 键后是否收到焦点
- elasticsearch - 从消息集中删除公共前缀和后缀
- sql - 检查值是否存在于多个表中 - Oracle SQL
- c# - 在 C# 中使用 Highcharts 进行服务器端渲染
- google-cloud-storage - 使用邮递员将多部分图像上传到谷歌云存储桶
- java - 通过 xslt 和 xsl:fo 生成 pdf 时根据 pdf 上的页码打印一些文本
- variables - 有没有办法获取范围内变量的名称和值?
- android - Android:从两个位图创建图像,位图下的位图