角度で複雑な反応形を管理する



tldr;
我々はすべての角度のアプリで複雑な形を管理する必要がありました、そしてそれは本当にすぐに厄介なことができます.すべての角度を使用して反応性フォームのために提供していることを確認して経験をより良くするのに役立ちます.これはネストされたFormGroupFormArray 本稿では、どのように複雑なフォームを管理するのに役立つかを見てみましょう.

What's the Problem?
私はフルタイムの仕事のために健康保険会社で働いています.あなたが想像できるように、我々は多くのフォームに対処し、それらのいくつかは非常に複雑です.例えば、1つのフォームは、雇い主が彼らの扶養家族を保険方針に加えるのを許します.従業員のフォームだけでは、記入する必要がある約20のフィールドがあり、それぞれの依存には、8つの必須フィールドと任意のアドレスフィールドのセットがあります.フォームに追加できる依存症の数に制限はありません.フロントエンドのロジックはすぐにコントロールから抜け出すようになりました.FormGroup.valid そして、再利用可能なフォームが保存される親コンポーネントにデータを発していることを確認します.複雑さは、我々がページを編集する必要があったどんな時間でも躊躇させました.最後に、私はページの別の観察をして、それを単純化して、角度の力を活用して、それが我々を自由のために我々に与えるものであると決めました.

The Form Setup
私は雇い主が彼らの健康計画に従業員と彼らの扶養家族を加えるのを許す仕事でフォームに取り組んでいました.複数の依存関係があるので、フォームは複雑になることができます.追加された各依存関係に対して(反応性)依存フォームを再利用しましたが、必要なフィールドが満たされたかどうかを手動で判断しました.毎回valuesChanged 観測可能な新しい値は、フォームの妥当性を決定する.私たちは従業員の形で似たようなことをしていました.また、手動でフォームの値をとり、必要に応じて親コンテナに出力するようにしました.
これは本当に複雑だったので、少しリファクタリングをしました.レイアウトは類似していました:ページのためのコンテナコンポーネント、従業員フォームコンポーネント、および0以上の従属するフォームがありました.しかし、コンテナコンポーネントの代わりに、新しいフォームに応答した後、各フォームの値を格納するOutput 発光、子コンポーネントは、フォームが初期化され、別のフォームに格納されているときにコンテナーコンポーネントにフォームを発行します.私は知っています、これは混乱します、しかし、この視覚化は助けなければなりません:
// container.component.ts

export class ContainerComponent {
    public form: FormGroup;

    constructor(private _fb: FormBuilder) {}

    ngOnInit() {
        this.form = this._fb.group({
            employeeForm: null,
            dependents: this._fb.array([])
        })
    }

    get dependentSubForms () {
        return this.form.get('dependents') as FormArray;
    }

    employeeFormReady(form: FormGroup) {
        this.form.setControl('employeeForm', form);
    }

    dependentSubFormReady(form: FormGroup) {
        this.dependentSubForms.push(form);
    }
}

このコンテナコンポーネントでは、メインフォームを作成します.これは、従業員のフォームとすべての依存症からデータを管理する方法です.フォームが初期化されると、メインフォームオブジェクトに追加されます.従業員のフォームの場合、我々はemployeeForm 制御するFormGroup , これは子要素に含まれます.依存するフォームは本質的に同じ方法で管理されますが、それらはFormArray つのコントロールの代わりに.
この時点で、ContainerComponent すべての更新された値を子供たちのコンポーネントから取得するだけでなく、その有効性をフォームに基づいて子供のコンポーネントから来て設定します.すべてのフォームから値を取得する準備ができたらform オブジェクトをContainerComponent すべてのデータを入力します.
あなたと遊ぶことができますa demo here on StackBlitz .

Conclusion
これは少し複雑に思えるかもしれませんが、以前に管理していた別の方法より簡単です.角度は本当に強力です、そして、我々にそれのためにその仕事をする必要はありません.これもフレキシブルである.これは私が上記の方法で使用することができますが、私はまた、マルチステップフォームを構築するために、同じ形式を最近使用しました.フォームの新しい部分がページに表示されるたびに、フォームに新しいコントロールを追加しました.各ステップを本当に簡単に管理しました.
これはこれを行う唯一の方法ではありません.提案された一つの方法はControlValueAccessor そして、それは私たちが今していることと比較する方法を見るために将来的に調べるもう一つの方法です