setModelObjectとmodelChanging / modelChanged
メモ。
PropertyModelなどを使ってフィールドをモデルの値に設定している場合、その値を直接書き換えてもモデルに値が反映しない。
この場合はsetModelObjectを使う。
ただしsetModelObjectを使っていても値が反映しない場合がある。
それはエラー後に前の値を入力した場合。
再現コードを確認した。
例えば、フォームA、setRequired(true)のテキストフィールドA、モデルA、フォームB、テキストフィールドBがあるとする。
フォームBをsubmitした場合にテキストフィールドBの値をsetModelObjectを使ってテキストフィールドAにコピーする。
- テキストフィールドBに「test」と入力してフォームBをsubmit
- テキストフィールドAには「test」と表示されているので、値を消してフォームAをsubmit
- エラーが出る
- もう一度テキストフィールドBにtestと入力してフォームBをsubmit
- テキストフィールドAに値が反映しない
要因は二つ
- フォーム送信でエラーが起きた場合、モデル値が更新されない
- 同じモデル値を設定しても表示は更新されない
ここでは3の段階でモデル値が更新されないので、modelの値は「test」になっているがテキストフィールドの表示では空欄になっているという状況が起こる。
再度setModelObjectを実行しても、model値が同じならmodelは何もしない。
Component#setDefaultModelObjectを見ると分かる。
public final Component setDefaultModelObject(final Object object) { ..... // Check whether this will result in an actual change if (!getModelComparator().compare(this, object)) { modelChanging(); model.setObject(object); modelChanged(); }
というわけで、エラーの後にモデルが更新されないっていう時は modelChanging / modelChanged を自分で呼び出す。