angular 2 remove all items from a formarray
我在formbuilder中有一个表单数组,并且正在动态更改表单,即从应用程序1等获得的点击加载数据。
我遇到的问题是,所有数据都已加载,但formarray中的数据仍然保留,只是将旧项与新项合并。
我如何清除该formarray仅包含新项目。
我已经试过了
1 2 | const control2 = <FormArray>this.registerForm.controls['other_Partners']; control2.setValue([]); |
但这不起作用。
有任何想法吗?
谢谢
在nginit中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | ngOnInit(): void { this.route.params.subscribe(params => { alert(params['id']); 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 }); } } ); } |
点击时未调用ngonitit
我有同样的问题。有两种方法可以解决此问题。
保留订阅
您可以通过循环调用
1 2 3 4 5 | clearFormArray = (formArray: FormArray) => { while (formArray.length !== 0) { formArray.removeAt(0) } } |
The advantage to this approach is that any subscriptions on your
formArray , such as that registered withformArray.valueChanges , will not be lost.
有关更多信息,请参见FormArray文档。
更干净的方法(但会破坏订阅引用)
您可以将整个FormArray替换为新的FormArray。
1 2 3 | clearFormArray = (formArray: FormArray) => { formArray = this.formBuilder.array([]); } |
This approach causes an issue if you're subscribed to the
formArray.valueChanges observable! If you replace the FromArray with a new array, you will lose the reference to the observable that you're subscribed to.
或者您可以简单地清除控件
1 2 3 4 5 | this.myForm= { name: new FormControl(""), desc: new FormControl(""), arr: new FormArray([]) } |
添加一些
1 2 | const arr = <FormArray>this.myForm.controls.arr; arr.push(new FormControl("X")); |
清除阵列
1 2 | const arr = <FormArray>this.myForm.controls.arr; arr.controls = []; |
当您选择并清除多个选项时,有时它不会更新视图。解决方法是添加
1 | arr.removeAt(0) |
更新
使用表单数组的一种更优雅的解决方案是在类的顶部使用getter,然后就可以对其进行访问。
1 2 3 | get inFormArray(): FormArray { this.myForm.get('inFormArray') as FormArray; } |
并在模板中使用
1 | other tags... |
重启:
1 | inFormArray.reset(); |
推:
1 | inFormArray.push(new FormGroup({})); |
删除索引处的值:1
1 | inFormArray.removeAt(1); |
从Angular 8开始,您可以使用
1 2 3 4 5 6 7 8 | const arr = new FormArray([ new FormControl(), new FormControl() ]); console.log(arr.length); // 2 arr.clear(); console.log(arr.length); // 0 |
对于以前的版本,建议的方法是:
1 2 3 | while (arr.length) { arr.removeAt(0); } |
https://angular.io/api/forms/FormArray#clear
角度8
只需在formArrays上使用
1 | (this.invoiceForm.controls['other_Partners'] as FormArray).clear(); |
警告!
Angular v6.1.7 FormArray文档说:
To change the controls in the array, use the push, insert, or removeAt
methods in FormArray itself. These methods ensure the controls are
properly tracked in the form's hierarchy. Do not modify the array of
AbstractControls used to instantiate the FormArray directly, as that
result in strange and unexpected behavior such as broken change
detection.
如果直接在
使用
1 2 3 | while (formArray.length !== 0) { formArray.removeAt(0) } |
Angular v4.4,如果您需要保存对FormArray实例的相同引用,请尝试以下操作:
1 2 3 4 5 | purgeForm(form: FormArray) { while (0 !== form.length) { form.removeAt(0); } } |
您可以轻松地为数组定义一个吸气剂,并按以下步骤清除它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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() } |
更新:Angular 8终于有了清除数组的方法
FormArray.clear()
使用FormArray.clear()删除FormArray中数组的所有元素
从Angular 8开始,您可以使用
这是一种更简便,更有效的替代方法,可以一次删除所有元素
提供了将要用匹配项替换数组中信息的数据结构,您可以使用
https://angular.io/docs/ts/latest/api/forms/index/FormArray-class.html#!#reset-anchor
patchValue(value: any[], {onlySelf, emitEvent}?: {onlySelf?: boolean,
emitEvent?: boolean}) : void Patches the value of the FormArray. It
accepts an array that matches the structure of the control, and will
do its best to match the values to the correct controls in the group.It accepts both super-sets and sub-sets of the array without throwing
an error.
1 2 3 4 5 6 7 | const arr = new FormArray([ new FormControl(), new FormControl() ]); console.log(arr.value); // [null, null] arr.patchValue(['Nancy']); console.log(arr.value); // ['Nancy', null] |
或者,您可以使用
reset(value?: any, {onlySelf, emitEvent}?: {onlySelf?: boolean,
emitEvent?: boolean}) : void Resets the FormArray. This means by
default:The array and all descendants are marked pristine The array and all
descendants are marked untouched The value of all descendants will be
null or null maps You can also reset to a specific form state by
passing in an array of states that matches the structure of the
control. The state can be a standalone value or a form state object
with both a value and a disabled status.
1 2 | this.arr.reset(['name', 'last name']); console.log(this.arr.value); // ['name', 'last name'] |
OR
1 2 3 | 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演示,演示了每个工具的非常简单的用法。
我从未尝试过使用formArray,我一直使用FormGroup,并且可以使用以下方法删除所有控件:
1 2 3 | Object.keys(this.formGroup.controls).forEach(key => { this.formGroup.removeControl(key); }); |
作为formGroup的FormGroup的实例。
我已经很晚了,但是我发现了其他不需要循环的方法。您可以通过将数组控件设置为空来重置数组。
下面的代码将重置您的数组。
为了保持代码干净,我为使用Angular 7及更低版本的任何人创建了以下扩展方法。这也可以用于扩展反应式表单的任何其他功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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; } |
如果数组具有100个项目,则while循环将需要很长时间才能删除所有项目。您可以清空FormArray的控件和值属性,如下所示。
clearFormArray =(formArray:FormArray)=> {formArray.controls = []; formArray.setValue([]); }