2017-09-21 1 views
2

プッシュで反応形式と変更検出を使用する。FormGroup内のFormArrayを更新するときに変更検出が機能しない

私はこれをどのようにして行うのかを調べています。これはかなり一般的ですが、私はこれを正しく行うための良い例を見つけることはできません。

ngOnInit内のサブスクリプション内のFormGroupのリストを含むFormArrayを更新しようとすると、FormArrayオブジェクトは更新されますが、変更検出がコンポーネントで強制されない限り、ビューはFormArrayグループを更新しません。このように更新された他のすべてのコントロールが動作しています。しかし、私がFormArrayを更新しようとしているように感じているのは間違っていて、私は変更検出を強制したくないし、強制したくないと感じています。

import { Component, OnInit, ChangeDetectionStrategy } from "@angular/core"; 
import { JournalTransactionService } from "app/accounting/shared-services/journal-transaction.service"; 
import { JournalEntry } from "accountingModels"; 
import { FormBuilder, FormGroup, FormArray } from "@angular/forms"; 
import { EntryLine } from "app/accounting/models/journal"; 

@Component({ 
    selector: "general-journal", 
    templateUrl: "./general-journal.component.html", 
    styleUrls: ["./general-journal.component.scss"], 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class GeneralJournalComponent implements OnInit { 
    journalEntry: JournalEntry; 
    journalEntryForm: FormGroup; 

    constructor(private _journalTransactionService: JournalTransactionService, private _formBuilder: FormBuilder) { } 

    get entryLines(): FormArray { 
    return <FormArray>this.journalEntryForm.get("entryLines"); 
    }; 

    ngOnInit() { 
    this.journalEntryForm = this._formBuilder.group(
     { 
     transactionId: "", 
     transactionDate: "", 
     autoReversalDate: "", 
     journalEntryType: "", 
     entryLines: this._formBuilder.array([]) 
     } 
    ); 
    this._journalTransactionService.getTransaction("", 80).subscribe(journalEntry => { 
     journalEntry.entryLines.forEach(entryLine => { 
     this.entryLines.push(this.entryLineMapper(entryLine)); 
     }); 

     this.journalEntryForm.patchValue(
     { 
      transactionId: journalEntry.transactionId, 
      transactionDate: journalEntry.transactionDate, 
      autoReversalDate: journalEntry.autoReversalDate, 
      journalEntryType: journalEntry.journalEntryType 
     } 
    ); 
    }); 
    } 


    private entryLineMapper = (entryLine: EntryLine): FormGroup => { 
    return this._formBuilder.group({ 
     accountId: entryLine.accountId, 
     controlId: entryLine.controlId, 
     debit: entryLine.debit, 
     credit: entryLine.credit, 
     description: entryLine.description, 
    }) 
    } 
} 

htmlの該当するセクション。トランザクションIDなどのバインドされている他のフィールドに入力すると、変更検出が実行され、テーブルが記入されます。サブスクライブブロックのパッチ値の後に変更検出を手動でトリガーすると、テーブルが記入されます。

<tbody formArrayName="entryLines"> 
     <tr *ngFor="let entryLine of entryLines.controls; index as i" [formGroupName]="i"> 
     <td> 
      <input type="text" class="form-control" formControlName="accountId"> 
     </td> 
     <td> 
      <input type="text" class="form-control" formControlName="controlId"> 
     </td> 
     <td> 
      <input type="text" class="form-control" formControlName="debit"> 
     </td> 
     <td> 
      <input type="text" class="form-control" formControlName="credit"> 
     </td> 
     <td> 
      <input type="text" class="form-control" formControlName="description"> 
     </td> 
     </tr> 
    </tbody> 

更新

今私は2つのコンポーネントの機能やフォームをラップしているいずれかの基本コンポーネントである1を作成していますこの問題を回避するには。これによりフォームを構築するためのデータをフォームコンポーネントへの入力として渡すことができ、OnPushの検出が機能するようになりました。私はこれで大丈夫ですが、FormArrayがFormGroupsまたはコントロールをサブスクリプション経由で追加し、新しい値をUIで更新できるようになっているように感じています。私はFormArrayコントロールがAbstracControlの観察可能な場合、これは動作すると思います。誰かがもっと良い解決策を持っているならば、私たちに知らせてください。

+0

OnPushの変更検出をオンにすると、formArrayが期待通りに表示されます。これは、OnPushが使用されているときに、* ngForがコントロールに変更が反映されていないためです。また、onInitのsubscribe関数本体の変更検出を手動でトリガーすることもできます。 FormArrayに公開され、観測可能なという公開されたプロパティがあるはずなので、反応的なフォームでOnPushを使用することができます。誰もがこれが問題だと私の問題を解決する唯一の2つの方法であることを確認できますか? – Strizzaflex

答えて

0

mapの代わりにpushを使用してください。

private entryLineBuilder = (entryLines: EntryLine[]): FormArray => { 
    return this._formBuilder.array(entryLines.push(this.entryLineMapper)); 
    } 

プッシュで配列を変更するので、角度変化の検出がトリガされるはずです。

+0

申し訳ありませんが、コードは呼び出されていません。それはちょうど失敗した試みでした。私は、entryLineMapperを呼び出して、subscribe内のformArrayにプッシュしています。投稿を更新して誰もが混乱しないようにします。 – Strizzaflex

+0

ああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ、あなたは 'journalEntry'の購読の中でデータを返送していますか?したがって、FormArrayに新しい行が追加されますが、ビューは更新されません。 –

+0

これは、2行のjsonファイルだけを読み込んでいます。そして、コンポーネントがフォーム配列にないすべてのフィールドを読み込んで、そのサブスクリプションにパッチが適用されてUIに表示されたとき。しかし、FormArrayの行はそこにありません。たとえば、transactionIdの入力値を変更すると、変更検出が実行され、行が表示されます。また、あなたが購読で変更検出のためにマークすると、それも動作しますが、それは間違っているようです。 – Strizzaflex

関連する問題