2012-02-03 10 views
3

私はカスタムWicketコンポーネントを使用してモデルオブジェクトをレンダリングしています。オブジェクトがnullの場合もあります。その場合、特定のdivが表示されます。コンポーネントのHTMLレンダリングコードでは、 "null"の場合と "nullでない"の場合の2つのdivがあり、他の内部マークアップもあります。一方は表示され、もう一方はマスクされます。Wicket "nullable"コンポーネントビュー

<div wicket:id="toDisplayWhenObjectIsNull"> 
    ... 
</div> 
<div wicket:id="toDisplayWhenObjectIsNotNull"> 
    <span wicket:id="label">...</span> 
    <table wicket:id="table">...</table> 
    ... 
</div> 

私が直面する問題は、モデルオブジェクトがnullの場合でも、Wicketが完全に2つのdivを作成することです。サブコンポーネントの建物(ラベル、テーブルなど)へのすべての呼び出しでは、私が面倒でエラーが発生しやすいnullであるかどうか、をチェックする必要があります。

​​

これに対する最初の解決策を分割するだろう特定のwicketサブコンポーネントの非ヌル部分を、自身のクラスまたはマスターコンポーネントの内部クラスのいずれかとして返します。 「nullでない」divの代わりにこのコンポーネントを挿入します。しかし、それは必要なファイル(リソース、HTML、Javaコード)の数を2倍にします。これは理想的ではありません。

2番目の解決策は、他のコンポーネントをカプセル化するための「デコレータ」コンポーネントを作成し、そのモデルオブジェクトのヌルネスをチェックすることです。コンポーネントがnullの場合は標準divが表示され、そうでない場合は装飾コンポーネントに依存します。私は境界線や複合パネルを使ってこれを実装しようとしましたが、動作させることはできません。

// Client code, Java 
ViewXPanel xpanel = new ViewXPanel("xpanel", new Model<X>(x)); 
add(xpanel); 

// HTML 
<div wicket:id="xpanel"/> 

OR、必要に応じて、クライアントコードでこのようなものを使用して、表示されたコンポーネントの「NULL可能」のクライアントを担当します:

// Client code, Java 
ViewXPanel xpanel = new NullableDecorator(?, ViewXPanel(...)); 
add(xpanel); 
私は何を達成したいことは、このような何かであります
+2

フラグメントを使用してみましたか?これらはこの問題に適用されるかもしれません。 – biziclop

+0

いいえ、それを効果的に見ると、これが解決策の一部になる可能性があります。私は彼らに試してみましょう。 –

+0

これはBorderで実現できないのだろうか?これは確かに一般的なケースですが、決して一般的なソリューションは必要ありませんでした。 2つの 'div'要素を作成するのは簡単です。もっと複雑で、ラップコンポーネントを作成します。とにかく、 'ShowOneBorder(Component1、Component2、IModel )'を作成して適切に追加し、 'onConfigure()'を使って見えるように修正することができます。 – jbrookover

答えて

0

biziclopで提案されているように、問題を回避するにはフラグメントを効果的に使用しています。ここでは説明のために説明しますが、「回答」としてフラグを立てません。

ViewX.html:

<wicket:panel ...> 
    <div wicket:id="mainPanel"></div> 
    <wicket:fragment wicket:id="nullFragment"> 
    ...markup for NULL case... 
    </wicket:fragment> 
    <wicket:fragment wicket:id="nonNullFragment"> 
    <h4><span wicket:id="theName"></span></h4> 
    ...other markup for non-NULL case... 
    </wicket:fragment> 
</wicket:panel 

ViewX.java:

public class ViewX extends Panel { 
    public ViewX(String id, IModel<X> xmodel) { 
    if (x == null) { 
     Fragment nullFragment = new Fragment("mainPanel", "nullFragment", null); 
     ... eventual markup if needed ... 
     add(nullFragment); 
    } else { 
     Fragment nonNullFragment = new Fragment("mainPanel", "nonNullFragment", null); 
     nonNullFragment.add(new Label("theName", new PropertyModel(xmodel, "name"))); 
     ... other markup ... 
     add(nonNullFragment); 
} } } 

私はまだ非上のいずれかの構図、相続や装飾で、これには本当に一般的な解決策を探していますnull対応のViewXパネル。

0

あなたがお勧めWicketのパターンを使用していない:(

代わりにモデルから何かを引っ張り、別のコンポーネントにそれを押し込むの:。

X myX = getModel().getModelObject(); 
Label label = new Label("label", myX == null ? null : formatY(myX.getY())); 

...モデルに正しい方法を使用します:

Label label = new Label("label", new AbstractReadonlyModel<Y>() { 
    public Y getObject() { 
     return formatY(getModel().getModelObject().getY()); 
    } 
}); 

は常に、このようにそれを行う

NULをテストする必要はありませんが。コンポーネント階層の最上位レベルの "toDisplayWhenObjectIsNull"と "toDisplayWhenObjectIsNotNull"の間の切り替えは別です。私はNULL値を表示することができるようにするためにやった

+0

まあ、ありがとう、しかし、それは質問に答えていない:あなたの指摘は*正確に*私が避けようとしているので、質問... –

+0

私はあなたが意味するものを理解していないようだ私はWicketが私に2つの部門を完全に築かせるよう強制しているのです - なぜですか? – svenmeier

0

は私がプレースホルダで空の文字列を置き換えるためにonComponentTagBody()をオーバーライドしている私自身のラベルのサブクラスを、作られたということでした。

/** 
* Since the converter is not invoked for null values, override this so that 
* empty string can be replaced with null display value. 
*/ 
@Override 
public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) 
{ 
    String value = getDefaultModelObjectAsString(); 
    replaceComponentTagBody(markupStream, openTag, 
          value.isEmpty()? "N/A": value); 
} 

これはそれを行います使用可能

// Client code, Java 
add(new MyLabel("label"); 

// HTML 
<div wicket:id="label"/> 

ローカリゼーションなどの設定でカスタマイズする必要がありますが、提供されている例から大きな図を得ることを願っています。