コード表をアプリに1回だけ書く
同じ選択肢を画面ごとに書き写さない。名前を付けて、使う所から指す。
業務のデータはコードで持って名前で見せる。shipped と保存して「出荷済」と出す、あれ。
やっかいなのは、同じコード表が画面のあちこちに出てくるところ。一覧の列、検索の条件、入力欄、詳細、帳票。見本のアプリを数えたら、同じ並びを4回書いていた。1回書くぶんには何ともないが、あとで「出荷済」を「発送済」に直すことになると、4か所を全部直さないといけない。3か所だけ直しても定義は通るし画面も出るので、残った1か所は誰かが見つけるまでそのままになる。
だからコード表はアプリに1回だけ書いて、使う所からは名前で指す。
app:
vocabularies:
- name: shipStatus
options:
- { value: 未出荷, label: 未出荷 }
- { value: 出荷済, label: 出荷済 }
pages:
- # …
search:
filters:
- { field: status, label: 状態, type: select, operator: equals, optionsOf: shipStatus }
table:
columns:
- { field: status, label: 状態, optionsOf: shipStatus }
form:
sections:
- fields:
- { field: status, label: 状態, type: select, optionsOf: shipStatus }optionsOf に書くのは語彙の名前だけ。中身は読み込むときに差し込まれるので、画面の側は今までどおり options が書いてあるのと同じように動く。
書ける場所は3つ
field(入力欄)・filter(検索条件)・column(一覧の列)。
このうち column に書けるのが要点。列は値を「見せるだけ」なので、以前は選択肢を持てなかった。持てない代わりに、同じ画面の入力欄や検索条件からこっそり借りていた。借りる相手が居る画面ならそれで足りるが、検索欄も入力欄も無い画面 ── 帳票や詳細 ── には借りる相手が居ない。結果、一覧では「出荷済」と出るのに帳票には shipped と刷られる、ということが起きていた。名前で指せるようになったので、借りる相手が居なくても正しい字が出る。
借りる動きは今も残してある。列に何も書かなければ、これまでどおり同じ画面から借りる。
列に選択肢そのものは書けない
column に書けるのは optionsOf だけで、options は書けない。
一見すると不便だが、これは意図してそうしている。見せる所に並びをもう一度書けるようにすると、入力側と一覧側で同じ表を2回持つことになる。片方だけ直したときに**入力欄では「発送済」なのに一覧では「出荷済」**という状態になり、しかもどちらも定義としては正しいので検証に出てこない。見せる所からは指すだけ、と決めておけば、この食い違いは原理的に起きない。
迷いどころ
optionsOf と optionsSource の違い。 optionsOf は定義の中に書いた表を指す。optionsSource は Repository から引く(選択肢を連動させる)。動かない表 ── 状態区分、社内/社外、伝票種別 ── は optionsOf、マスタから引くもの ── 取引先、商品、部署 ── は optionsSource。
両方は書かない。 同じ所に options と optionsOf の両方を書くと、その場に書いた並びが勝って optionsOf は一度も効かない。語彙を直したのにその画面だけ古い字のまま、という形で出る。検証が言うので、言われたら片方を消す。
名前は打ち間違える。 optionsOf が指す先が無いと、選択肢は空のまま画面が出る。エラーにはならず、その画面を開いて選択肢を押すまで気づけない。これも検証が拾うので、「もしかして」が出たら素直に従うのが早い。
書けるキー
| キー | 書く場所 | 型 | 必須 | 既定値 | 有効なページ種別 | 説明 |
|---|---|---|---|---|---|---|
vocabularies | app | array → vocabulary | 任意 | — | すべて | Code lists shared by every page. A screen refers to one with optionsOf: <name> instead of repeating the list, so a reworded label changes in one place instead of drifting between the list, the search box and the detail screen. |
name | vocabulary | string | 必須 | — | すべて | Name used by optionsOf. Unique within the app. |
optionsOf | column | string | 任意 | — | crud dashboard detail form master report search wizard | Name of a vocabulary declared in app.vocabularies. The options come from there, so one code list is written once and read by every screen that shows it. Inline options on the same node wins; an undeclared name is a warning (unknown-vocabulary) because the list would silently be empty. |
optionsOf | field | string | 任意 | — | crud dashboard detail form master report search wizard | Name of a vocabulary declared in app.vocabularies. The options come from there, so one code list is written once and read by every screen that shows it. Inline options on the same node wins; an undeclared name is a warning (unknown-vocabulary) because the list would silently be empty. |
optionsOf | filter | string | 任意 | — | crud dashboard master report search | Name of a vocabulary declared in app.vocabularies. The options come from there, so one code list is written once and read by every screen that shows it. Inline options on the same node wins; an undeclared name is a warning (unknown-vocabulary) because the list would silently be empty. |
この表は spec/reference.json から生成している(JSON Schema が正)。手元では npx -p @hatake-fw/api hatake reference <キー名> で同じものが引ける。
実物を見る
デモアプリの「受注照会」がこれを使っている。 デモを開く