ログ日記

作業ログと日記とメモ

setModelObjectとmodelChanging / modelChanged

メモ。

PropertyModelなどを使ってフィールドをモデルの値に設定している場合、その値を直接書き換えてもモデルに値が反映しない。
この場合はsetModelObjectを使う。


ただしsetModelObjectを使っていても値が反映しない場合がある。
それはエラー後に前の値を入力した場合。


再現コードを確認した。
例えば、フォームA、setRequired(true)のテキストフィールドA、モデルA、フォームB、テキストフィールドBがあるとする。
フォームBをsubmitした場合にテキストフィールドBの値をsetModelObjectを使ってテキストフィールドAにコピーする。

  1. テキストフィールドBに「test」と入力してフォームBをsubmit
  2. テキストフィールドAには「test」と表示されているので、値を消してフォームAをsubmit
  3. エラーが出る
  4. もう一度テキストフィールドBにtestと入力してフォームBをsubmit
  5. テキストフィールド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 を自分で呼び出す。