以角度移除 FormArray 中的所有项

我在 FormBuilder 中有一个表单数组,并且我正在动态地更改表单,例如,单击加载来自应用程序1的数据等。

我遇到的问题是,除了 FormArray 中的数据之外,所有的数据都加载进来,并且只是将旧项与新项连接起来。

如何清除 FormArray 以使其只包含新项。

我试过了

const control2 = <FormArray>this.registerForm.controls['other_Partners'];
control2.setValue([]);

但是没用。

有什么想法吗?

ngOnInit(): void {
this.route.params.subscribe(params => {
if (params['id']) {
this.id = Number.parseInt(params['id']);
} else { this.id = null;}
});
if (this.id != null && this.id != NaN) {
alert(this.id);
this.editApplication();
this.getApplication(this.id);
} else {
this.newApplication();
}
}


onSelect(Editedapplication: Application) {
this.router.navigate(['/apply', Editedapplication.id]);
}


editApplication() {
this.registerForm = this.formBuilder.group({
id: null,
type_of_proposal: ['', Validators.required],
title: ['', [Validators.required, Validators.minLength(5)]],
lead_teaching_fellow: ['', [Validators.required, Validators.minLength(5)]],
description: ['', [Validators.required, Validators.minLength(5)]],
status: '',
userID: JSON.parse(localStorage.getItem('currentUser')).username,
contactEmail: JSON.parse(localStorage.getItem('currentUser')).email,
forename: JSON.parse(localStorage.getItem('currentUser')).firstname,
surname: JSON.parse(localStorage.getItem('currentUser')).surname,
line_manager_discussion: true,
document_url: '',
keywords: ['', [Validators.required, Validators.minLength(5)]],
financial_Details: this.formBuilder.group({
id: null,
buying_expertise_description: ['', [Validators.required, Validators.minLength(2)]],
buying_expertise_cost: ['', [Validators.required]],
buying_out_teaching_fellow_cost: ['', [Validators.required]],
buying_out_teaching_fellow_desc: ['', [Validators.required, Validators.minLength(2)]],
travel_desc: ['', [Validators.required, Validators.minLength(2)]],
travel_cost: ['', [Validators.required]],
conference_details_desc: ['', [Validators.required, Validators.minLength(2)]],
conference_details_cost: ['', [Validators.required]],
}),


partners: this.formBuilder.array([
//this.initEditPartner(),
//this.initEditPartner()
// this.initMultiplePartners(1)
]
),
other_Partners: this.formBuilder.array([
//this.initEditOther_Partners(),
])
});
}


getApplication(id) {
this.applicationService.getAppById(id, JSON.parse(localStorage.getItem('currentUser')).username)
.subscribe(Response => {
if (Response.json() == false) {
this.router.navigateByUrl('/');
} else {
this.application = Response.json();
for (var i = 0; i < this.application.partners.length;i++) {
this.addPartner();
}
for (var i = 0; i < this.application.other_Partners.length; i++) {
this.addOther_Partner();
}


this.getDisabledStatus(Response.json().status);
(<FormGroup>this.registerForm) .setValue(Response.json(), { onlySelf: true });
}
});
}

单击时不调用 ngOnInit

178523 次浏览

我也有同样的问题,解决这个问题有两种方法。

保留订阅

通过在循环中调用 removeAt(i)函数,可以手动清除每个 FormArray 元素。

clearFormArray = (formArray: FormArray) => {
while (formArray.length !== 0) {
formArray.removeAt(0)
}
}

这种方法的优点是不会丢失 formArray上的任何订阅,例如用 formArray.valueChanges注册的订阅。

有关更多信息,请参见 FormArray 文档


更干净的方法(但中断订阅引用)

您可以用一个新的 FormArray 替换整个 FormArray。

clearFormArray = (formArray: FormArray) => {
formArray = this.formBuilder.array([]);
}

如果您订阅了 formArray.valueChanges可观察到的内容,那么这种方法会导致一个问题!如果用新数组替换 FromArray,则将丢失对订阅的可观察数组的引用。

提供了用于替换数组中信息的数据结构,该结构与已经存在的信息相匹配,可以使用 patchValue

Https://angular.io/docs/ts/latest/api/forms/index/formarray-class.html#!#reset-anchor

PatchValue (value: any [] ,{ onlySelf,emitEvent } ? : { onlySelf? : boolean, }) : void 修补 FormArray 的值 接受与控件结构匹配的数组,并将 尽最大努力将值与组中的正确控件匹配。

它接受数组的超集和子集,而不引发 一个错误。

const arr = new FormArray([
new FormControl(),
new FormControl()
]);
console.log(arr.value);   // [null, null]
arr.patchValue(['Nancy']);
console.log(arr.value);   // ['Nancy', null]

或者,您可以使用 reset

复位(值? : any,{ onlySelf,emitEvent } ? : { onlySelf? : boolean, : boolean }) : void 重置 FormArray 默认值:

数组和所有后代都被标记为原始数组和所有 所有子孙后代的价值 空或空映射还可以通过以下方法重置为特定的窗体状态 传入一个状态数组,这些状态数组与 状态可以是独立的值,也可以是窗体状态对象 同时具有值和禁用状态。

this.arr.reset(['name', 'last name']);
console.log(this.arr.value);  // ['name', 'last name']

或者

this.arr.reset([   {value: 'name', disabled: true},   'last' ]);
console.log(this.arr.value);  // ['name', 'last name']
console.log(this.arr.get(0).status);  // 'DISABLED'

这里有一个分叉的 Plunker 演示,它来自我早期的一些工作,演示了如何非常简单地使用每一种方法。

或者您可以简单地清除控件

this.myForm= {
name: new FormControl(""),
desc: new FormControl(""),
arr: new FormArray([])
}

加点什么 array

const arr = <FormArray>this.myForm.controls.arr;
arr.push(new FormControl("X"));

清除阵列

const arr = <FormArray>this.myForm.controls.arr;
arr.controls = [];

当您选择并清除多个选项时,有时它不会更新视图

arr.removeAt(0)

更新

使用表单数组的一个更优雅的解决方案是在类的顶部使用 getter,然后您就可以访问它了。

get inFormArray(): FormArray {
this.myForm.get('inFormArray') as FormArray;
}

并将其用于模板

<div *ngFor="let c of inFormArray; let i = index;" [formGroup]="i">
other tags...
</div>

重置:

inFormArray.reset();

推:

inFormArray.push(new FormGroup({}));

删除索引处的值: 1

inFormArray.removeAt(1);

更新2:

获取部分对象,获取所有错误作为 JSON 和许多其他特性,使用 NaoFormsModule

如果需要保存对 FormArray 实例的相同引用,请尝试以下操作:

purgeForm(form: FormArray) {
while (0 !== form.length) {
form.removeAt(0);
}
}

警告!

Angular v6.1.7 FormArray 文档表示:

若要更改数组中的控件,请使用 push、 insert 或 RemoveAt 这些方法确保控件是 在窗体的层次结构中正确跟踪。不要修改 用于直接实例化 FormArray 的 导致奇怪和意想不到的行为,如破碎的变化 侦测。

如果您直接在 controls数组上使用 splice函数作为建议的答案之一,请记住这一点。

使用 removeAt函数。

  while (formArray.length !== 0) {
formArray.removeAt(0)
}

如果 array 有100个条目,那么循环需要很长时间来删除所有条目。您可以清空 FormArray 的控件和值属性,如下所示。

ClearFormArray = (formArray: FormArray) = > { formArray.control = [] ; formArray.setValue ([]) ; }

从 Angular 8 + 开始,你可以使用 clear()来移除 FormArray 中的所有控件:

const arr = new FormArray([
new FormControl(),
new FormControl()
]);
console.log(arr.length);  // 2


arr.clear();
console.log(arr.length);  // 0

对于以前的版本,推荐的方法是:

while (arr.length) {
arr.removeAt(0);
}

Https://angular.io/api/forms/formarray#clear

更新: 角8终于得到了清除阵列的方法 FormArray. clear ()

为了保持代码的整洁,我已经创建了下面的扩展方法,任何人使用角7及以下。这也可以用来扩展 Reactive Forms 的任何其他功能。

import { FormArray } from '@angular/forms';


declare module '@angular/forms/src/model' {
interface FormArray {
clearArray: () => FormArray;
}
}


FormArray.prototype.clearArray = function () {
const _self = this as FormArray;
_self.controls = [];
_self.setValue([]);
_self.updateValueAndValidity();
return _self;
}


角度8

只需在 formArray 上使用 clear()方法:

(this.invoiceForm.controls['other_Partners'] as FormArray).clear();

从角度8开始,你可以使用 this.formArray.clear()来清除表单数组中的所有值。 相对于逐个删除所有元素,这是一种更简单、更有效的替代方法

我从未尝试过使用 formArray,我一直在使用 FormGroup,您可以使用以下方法删除所有控件:

Object.keys(this.formGroup.controls).forEach(key => {
this.formGroup.removeControl(key);
});

是 FormGroup 的一个实例。

我已经迟到很久了,但是我找到了其他不需要循环的方法。可以通过将数组控件设置为空来重置数组。

下面的代码将重置数组。

this.form.setControl('name', this.fb.array([]))

您可以很容易地为数组定义一个 getter 并清除它,如下所示:

  formGroup: FormGroup
constructor(private fb: FormBuilder) { }


ngOnInit() {
this.formGroup = this.fb.group({
sliders: this.fb.array([])
})
}
get sliderForms() {
return this.formGroup.get('sliders') as FormArray
}


clearAll() {
this.formGroup.reset()
this.sliderForms.clear()
}

使用 FormArray.clear ()删除 FormArray 中数组的所有元素

如果你正在使用 Angular 7或者之前的版本,并且你不能访问 clear ()方法,有一种方法可以实现,而不需要做任何循环:

yourFormGroup.controls.youFormArrayName = new FormArray([]);

很简单

formArray.clear()

就足够了

(this.questionForm.controls['answers'] as FormArray).clear();