フォームビルダー内にフォーム配列があり、フォームを動的に変更しています。つまり、アプリケーション1からのデータのクリックロードなどです。
私が抱えている問題は、すべてのデータが読み込まれますが、formarrayのデータは残り、古いアイテムと新しいアイテムを連結するだけです。
そのformarrayをクリアして、新しいアイテムのみを持つようにするにはどうすればよいですか。
私はこれを試しました
const control2 = <FormArray>this.registerForm.controls['other_Partners'];
control2.setValue([]);
しかし、それは機能しません。
何か案は?ありがとう
nginitで
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はクリック時に呼び出されていません
同じ問題がありました。この問題を解決するには2つの方法があります。
ループでremoveAt(i)
関数を呼び出すことにより、各FormArray要素を手動でクリアできます。
clearFormArray = (formArray: FormArray) => {
while (formArray.length !== 0) {
formArray.removeAt(0)
}
}
このアプローチの利点は、
formArray.valueChanges
に登録されているようなformArray
のサブスクリプションが失われないことです。
詳細については、 FormArray documentation を参照してください。
FormArray全体を新しいものに置き換えることができます。
clearFormArray = (formArray: FormArray) => {
formArray = this.formBuilder.array([]);
}
formArray.valueChanges
observableにサブスクライブしている場合、このアプローチは問題を引き起こします! FromArrayを新しい配列に置き換えると、サブスクライブしているObservableへの参照が失われます。
または、単にコントロールをクリアすることができます
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)
フォーム配列を使用するよりエレガントなソリューションは、クラスの最上部でゲッターを使用してからアクセスできるようにすることです。
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);
Angular v4.4では、FormArrayのインスタンスへの同じ参照を保存する必要がある場合、これを試してください:
purgeForm(form: FormArray) {
while (0 !== form.length) {
form.removeAt(0);
}
}
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);
}
警告!
Angular v6.1.7 FormArrayのドキュメント の意味:
配列内のコントロールを変更するには、FormArray自体のPush、insert、またはremoveAtメソッドを使用します。これらのメソッドは、コントロールがフォームの階層で適切に追跡されるようにします。 FormArrayを直接インスタンス化するために使用されるAbstractControlsの配列を変更しないでください。変更が検出されないなどの奇妙で予期しない動作が発生します。
回答の1つとしてsplice
関数をcontrols
配列で直接使用している場合は、このことに留意してください。
removeAt
関数を使用します。
while (formArray.length !== 0) {
formArray.removeAt(0)
}
配列内の情報を既存のものと一致するものに置き換えるデータ構造を提供し、patchValue
を使用できます
https://angular.io/docs/ts/latest/api/forms/index/FormArray-class.html#!#reset-anchor
patchValue(value:any []、{onlySelf、emitEvent} ?: {onlySelf ?: boolean、emitEvent ?: 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
を使用することもできます
reset(value ?: any、{onlySelf、emitEvent} ?: {onlySelf ?: boolean、emitEvent ?: boolean}):void FormArrayをリセットします。これはデフォルトで以下を意味します:
配列とすべての子孫は初期状態とマークされます配列とすべての子孫は未処理とマークされますすべての子孫の値はnullまたはnullマップになりますコントロールの構造に一致する状態の配列を渡すことで、特定のフォーム状態にリセットすることもできます。状態は、スタンドアロン値、または値と無効ステータスの両方を持つフォーム状態オブジェクトです。
this.arr.reset(['name', 'last name']);
console.log(this.arr.value); // ['name', 'last name']
OR
this.arr.reset([ {value: 'name', disabled: true}, 'last' ]);
console.log(this.arr.value); // ['name', 'last name']
console.log(this.arr.get(0).status); // 'DISABLED'
Here's 私の以前の作品から分岐したPlunkerデモで、それぞれの非常に単純な利用をデモしています。
更新:Angular 8がようやくArray FormArray.clear()をクリアするメソッドを取得しました
While配列に数百のアイテムがある場合、すべてのアイテムを削除するには長い時間がかかります。以下のように、FormArrayのコントロールと値プロパティの両方を空にすることができます。
clearFormArray =(formArray:FormArray)=> {formArray.controls = []; formArray.setValue([]); }
コードをきれいに保つために、Angular 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
formArraysでclear()
メソッドを使用するだけです:
(this.invoiceForm.controls['other_Partners']).clear();
最新バージョンでは、Form Array.reset()を使用できます