ReactiveForms を動的に構築する Angular アプリを作ってみた

Angular アプリで、あるデータモデルに関する CRUD 操作を行う画面って、もう少し簡単に作れないかしら。例えばデータモデルを JSON で定義すると、それを編集できるフォームが自動生成されるような、Rails の Scaffold みたいなヤツ…。

…と思って、作ってみた。Angular Utilities にて、Dynamic Generate Form として公開している。

ソースコードは以下より、./src/app/pages/dynamic-generate-form/ 配下を見ると良い。

一応使い方を説明。

一応、どんな JSON を渡せるのかの説明。

controls に突っ込める1項目のデータは以下のとおり。

こうした JSON モデルを用意してやれば、フォームが自動生成される。

どのように実現しているかというと、JSON データを基にフォームを構築し、画面に配置した FormGroup に代入している。ビュー部分はコンポーネント HTML 側に「ラジオボタンの項目」「チェックボックスの項目」みたいな塊を用意していて、FormGroup の中身をループして全項目表示させている。

作った時の話

ReactiveForms をコンポーネント側から動的に構築する時のお作法の勉強になった。

特に、チェックボックスに関しては FormArray を構築する、というところが最初よく分からなくて調べた。FormArray にすれば複数選択された時も配列としてデータを渡せる。セレクトボックスは自動的にそうしてくれるんだけどな…。

↑ 今回作ったモノに近いことをやっている記事があった。コンポーネント HTML の構造なんかは大体同じ。

次に、ReactiveForms 部品に対して、[disabled]="myModel.isDisabled" みたいにバインディングしようとすると、ワーニングが表示されてしまった。

[disabled] ではなく、[attr.disabled] を使うと上手く行った。

あと、JSON ファイルを import * as で読み込もうとするとコンパイルエラーになってしまったので、./src/typings.d.ts に以下のようにコードを追加した。

// JSON ファイルを import * as jsonFile from './example.json'; で読み込めるようにするため定義
declare module '*.json' {
  const value: any;
  export default value;
}

このようにすると、import したデータに default プロパティが出来てしまうので、適宜 delete myJson.default; などとして削除しておく。

色々と難アリ

当然だが、このような作りだと、色々と難がある。

というか、画面周りは結局デザイン変更のために手を入れないといけないので、本当は ng generate の拡張機能みたいな感じで、所定のデータモデルに沿った雛形ファイルを自動生成する仕組みを取りたいと思った。

Schematics という仕組みで実現できる

調べてみると、Angular 6 から登場した Schematics という方式に則って Angular 向け npm パッケージを作ると、ng generate コマンドを拡張できるらしい。

さらに見ていると、既に Angular アプリ向けに CRUD を行う Scaffold を提供してくれる Schematics を作りかけている人を見つけた。

この angular-crud というのが、自分が思っていたモノにかなり近い。

ただ、今のところ Schematics に対応するライブラリの作り方が紹介されている記事が少なく、イマイチ作り方が分からず断念中…。