あまり考えず、Modelを使っていた(使っていなかった?)ので、
ふと調べてみたところ、いろいろできそうだったので、
調べてみた結果をまとめてみます。
Example ソースコードに対するリンク集。
使用しているWicketのVersion
7.2.0
Modelについての説明文書
以下のWeb上の文書でWicketのModelとは何かは理解できそうです。
-
第2回 コンポーネントとモデル
まず、最初にこれを一読しました。 -
Wicketのユニットテスト機能
WicketTesterについてのpdfですが、後半に、Modelについての説明付録があります。 -
ModelとPropertyModel
ModelとPropertyModelの実装の説明 -
Apache Wicket ベストプラクティス(日本語)
「常にModelを使え」に大事なことが書いてありました。
Modelパッケージ配下のClass一覧
wicket/wicket-core/src/main/java/org/apache/wicket/model at wicket-7.x · apache/wicket · GitHub
から一覧表は作成しました。
Class名 | Notes |
---|---|
AbstractPropertyModel.java | PropertyModel.javaの基底クラス 省略 |
AbstractReadOnlyModel.java | ReadOnlyを保証したい時に使う |
AbstractWrapModel.java | ModelオブジェクトをWrapして、一部を加工する時に使用する |
ChainingModel.java | PropertyModel.java,CompoundPropertyModel.javaの基底クラス 省略 |
ComponentDetachableModel.java | シリアライズするには忍びない大きいオブジェクト生成時に使用する |
ComponentModel.java | Panel等ページテンプレートクラスにデータクラスを設定 |
ComponentPropertyModel.java | Panel等ページテンプレートクラスにデータクラスを設定、値はコピーしてくれる |
CompoundPropertyModel.java | 値は自動コピーもする。単純コピーでないものはbindできる。 |
IChainingModel.java | IFなので省略 |
IComponentAssignedModel.java | IFなので省略 |
IComponentInheritedModel.java | IFなので省略 |
IDetachable.java | IFなので省略 |
IModel.java | IFなので省略 |
IModelComparator.java | IFなので省略 |
IObjectClassAwareModel.java | IFなので省略 |
IPropertyReflectionAwareModel.java | IFなので省略 |
IWrapModel.java | IFなので省略 |
LoadableDetachableModel.java | Sessionに大きなデータを積まないようにするためのModel |
Model.java | オーソドックなModel |
PropertyModel.java | CompoundPropertyModel.javaがあるので、あまり使用機会はないかもしれない |
ResourceModel.java | ResourceBundleを扱う際に使用するModel |
StringResourceModel.java | メッセージ出力時などに使用する。1つだけならgetString() |
AbstractReadOnlyModel.java
- 参考サイト
** Java Code Example org.apache.wicket.model.AbstractReadOnlyModel
** 最新WicketのGenericsぶりに、早くも敗れ去る – タロタローグ ブログ
AbstractWrapModel.java
大きいModelがあるとして、その中の一部のデータを取り出して使用する用途に使うModelかと思います。
大元のモデルが変われば、そのモデルに連動して、
AbstractWrapModel.java
を使用したModelの返すデータが切り替わる。
- 参考サイト
** Java Code Example
** Java Code Example
ComponentDetachableModel.java
exmampleが見つからなかったです..
- 参考サイト
** Detachable Models - Apache Wicket - Apache Software Foundation
** 11 Wicket models and forms 7.x
ComponentModel.java
exmampleが見つからなかったです..
参考情報もなしですが、
ComponentPropertyModel.java
のexmampleはあるため使いかたの想像はできる。
実装を見るかぎり、あまり使う機会はなさそう.
ComponentPropertyModel.java
Panelとデータを切り離すための、modelに見受けられます。
Panelはデンプレートで、内部のデータをコントロールしたい時に使用する。
単純なデータクラスから、値のコピーの場合は、このクラスを、
単純なコピーでない場合、 上記のComponentModel.java
を使う。
CompoundPropertyModel.java
このクラスはよく使いそうです。
使い方を詳細に調べてみました。
- 参考サイト
関連:ListItem#setModel()について
ListItemには、ListItem#setModel()、ListItem#setDefaultModel()がある。
setDefaultModel()は、Generics化の際に追加されたメソッドなので、
java5以降で実装しているなら、特に使用しなくてよい。
- ListItem#setDefaultModel()
CompoundPropertyModel<Blog> blogModel = new CompoundPropertyModel<>(item.getModelObject()); item.setDefaultModel(blogModel);
ではなくて、以下の記述でよい。
-
ListItem#setModel()
CompoundPropertyModel<Blog> blogModel = new CompoundPropertyModel<>(item.getModelObject()); item.setModel(blogModel);
-
参考サイト
関連:MarkupContainer#setDefaultModel()について
Pageクラス、Panelクラス等には、setModel()はなく、setDefaultModel()だけがある。
※setModel、getModelが使う機会がないから?
関連:BoundCompoundPropertyModelについて
wicket1.4くらいまでは、BoundCompoundPropertyModelというclassがあり、
以下の、bindメソッドがあった。
-
BoundCompoundPropertyModel#bind(final Component component, final String propertyExpression)
/** * Adds a property binding. * * @param component * The component to bind * @param propertyExpression * A property expression pointing to the property in this model * @return The component, for convenience in adding components */ public Component bind(final Component component, final String propertyExpression) { bind(component, propertyExpression, null); return component; }
-
BoundCompoundPropertyModel#bind(final Component component, final Class type)
/** * Adds a type conversion binding. * * @param component * The component to bind * @param type * The type of the property * @return The component, for convenience in adding components */ public Component bind(final Component component, final Class type) { bind(component, component.getId(), type); return component; }
wicket1.4でBoundCompoundPropertyModelは、非推奨クラスになり、wicket1.5以降は削除されている。
上記のbindメソッドの代わりに?、CompoundPropertyModelにbindメソッドが追加された。
- CompoundPropertyModel#bind(String property)
/** * Binds this model to a special property by returning a model that has this compound model as * its nested/wrapped model and the property which should be evaluated. This can be used if the * id of the Component isn't a valid property for the data object. * * @param property * the name that will be used to find * @return The IModel that is a wrapper around the current model and the property * @param <S> * the type of the property */ public <S> IModel<S> bind(String property) { return new PropertyModel<>(this, property); }
関連:PropertiesListViewについて
ListViewで、CompoundPropertyModelを使えるようになる。
ものとして認識しました。 以下のように書けます。
CompoundPropertyModel#bind()とかしたい場合は、
ListItem#getModel()の戻りを、Castする必要があり、それが不恰好ですね..
// -------------------------------------------
// New LitView
ListView<Video> videoListView = new PropertyListView<Video>("videos", videos) {
private static final long serialVersionUID = 4949588177564901031L;
@Override
protected void populateItem(ListItem<Video> item) {
item.add(new Label("title"));
WebComponent webComponent = new WebComponent("videoSrc");
CompoundPropertyModel<Video> model = (CompoundPropertyModel<Video>) item.getModel();
webComponent.add(AttributeModifier.replace("src", model.bind("embedUrl")));
item.add(webComponent);
}
};
// --------------------
add(videoListView);
正直使えるユースケースが少ない? ように感じました。
ListItem直下の階層に対してしか使えない?
それほど、直下の階層にプロパティ値を設定することは少ないように思います。
設定できるプロパティと出来ないプロパティが混じり、ListViewでいいのではとなりそうです。
中、大規模開発だったら、ListViewしか使わないか、ハイブリッドOKかを決めておく方か吉かもしれません。
LoadableDetachableModel.java
Sessionに積んで、シリアライズするには大きすぎるオブジェクト(きっとListデータ)を、
Sessionには設定せず、毎回ストレージから読み出す用途に使用します。
- 試しに
LoadableDetachableModel
を記載したプログラムの抜粋 FestivalRepositoryはJPAのリポジトリクラスで全件リスト 取得処理が走ります。
LoadableDetachableModel<List<Festival>> festivals = new LoadableDetachableModel<List<Festival>>() {
private static final long serialVersionUID = 7474274077691068779L;
@Override
protected List<Festival> load() {
// Get ListView Elems
FestivalRepository repository = InjectorHolder._new(FestivalRepository.class);
return repository.findAll();
}
};
- 参考サイト
LoadableDetachableModel
の処理の肝は、検索キーを保持するケースかと思われます。
キーはModel内に保持して、再度getObject()
が呼び出された際に、復旧できるようにしているようです。
Model.java
簡単な動的Modelを作るために使用するものだという理解です。
getObject
を実装して、Method内で値を取得。
PropertyModel.java
ComponentPropertyModel
を使う機会が多いかと思います。
ResourceModel.java
あまり使用する機会はなさそうです。
StringResourceModel.java
の方にはメッセージ設定機能があり、こちらにはありません。
単純な文字列の取得ではない場合、getString()
ではなくこちらで実装する。
StringResourceModel.java
以下、サイトの説明がわかりやすかったです。
StringResourceModelは、LoadableDetachableModelを継承しているので、
シリアライズの対象外になりそうです。
包括的な日本語ドキュメントや書籍が少ないのは、
やはりちょっと学習するの大変に思います。
以上です。
コメント