プッシュで反応形式と変更検出を使用する。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の観察可能な場合、これは動作すると思います。誰かがもっと良い解決策を持っているならば、私たちに知らせてください。
OnPushの変更検出をオンにすると、formArrayが期待通りに表示されます。これは、OnPushが使用されているときに、* ngForがコントロールに変更が反映されていないためです。また、onInitのsubscribe関数本体の変更検出を手動でトリガーすることもできます。 FormArrayに公開され、観測可能なという公開されたプロパティがあるはずなので、反応的なフォームでOnPushを使用することができます。誰もがこれが問題だと私の問題を解決する唯一の2つの方法であることを確認できますか? –
Strizzaflex