web-dev-qa-db-ja.com

angular 2はformarrayからすべてのアイテムを削除します

フォームビルダー内にフォーム配列があり、フォームを動的に変更しています。つまり、アプリケーション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はクリック時に呼び出されていません

53
Karl O'Connor

同じ問題がありました。この問題を解決するには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への参照が失われます。

97
CamelD

または、単にコントロールをクリアすることができます

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);
22
Pian0_M4n

Angular v4.4では、FormArrayのインスタンスへの同じ参照を保存する必要がある場合、これを試してください:

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

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

6
crappylime

警告!

Angular v6.1.7 FormArrayのドキュメント の意味:

配列内のコントロールを変更するには、FormArray自体のPush、insert、またはremoveAtメソッドを使用します。これらのメソッドは、コントロールがフォームの階層で適切に追跡されるようにします。 FormArrayを直接インスタンス化するために使用されるAbstractControlsの配列を変更しないでください。変更が検出されないなどの奇妙で予期しない動作が発生します。

回答の1つとしてsplice関数をcontrols配列で直接使用している場合は、このことに留意してください。

removeAt関数を使用します。

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

配列内の情報を既存のものと一致するものに置き換えるデータ構造を提供し、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デモで、それぞれの非常に単純な利用をデモしています。

3
silentsod

更新:Angular 8がようやくArray FormArray.clear()をクリアするメソッドを取得しました

2
nightingale2k1

While配列に数百のアイテムがある場合、すべてのアイテムを削除するには長い時間がかかります。以下のように、FormArrayのコントロールと値プロパティの両方を空にすることができます。

clearFormArray =(formArray:FormArray)=> {formArray.controls = []; formArray.setValue([]); }

0
user3067875

コードをきれいに保つために、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;
}

0
Danielok1993

角度8

formArraysでclear()メソッドを使用するだけです:

(this.invoiceForm.controls['other_Partners']).clear();
0
MajiD

最新バージョンでは、Form Array.reset()を使用できます

0
dam