2012-02-03 50 views
3

很經常,我使用自定義的Wicket組件來渲染模型對象。對象有時可能爲空,在這種情況下會顯示特定的div。在組件HTML呈現代碼中,我有兩個div,一個用於「null」情況,一個用於「非null」情況,以及其他一些內部標記。顯示一個,而另一個被屏蔽。Wicket「nullable」組件視圖

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

我面對的問題是,Wicket迫使我完全建立兩個div,即使模型對象爲null。在子組件建築(標籤,表格等)的所有調用我要檢查NULL的含量,這是麻煩且容易出錯:

​​

第一個解決方案,這將是分裂特定檢票子組件中的非零部分,或者是它自己的類或主組件的內部類;並插入此組件代替「非空」div。但是需要的文件數量增加了一倍(資源,HTML,Java代碼)。這並不理想。

第二個解決方案是泛型,將創建一個「裝飾器」組件來封裝任何其他組件,並檢查其模型對象是否爲空。如果組件爲空,那麼它將顯示一個標準div,如果不是,它將依賴於裝飾組件。我試圖用邊框或複合面板來實現這一點,但我無法設法使其工作。我想實現的是這樣的:

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

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

,或者,如果有必要,使客戶端負責所顯示的組件的「空性」,使用像這樣的客戶端代碼:

// Client code, Java 
ViewXPanel xpanel = new NullableDecorator(?, ViewXPanel(...)); 
add(xpanel); 
+2

您是否嘗試過使用Fragments?它們可能適用於這個問題。 – biziclop 2012-02-03 13:29:07

+0

不,有效地看着他們這可能是解決方案的一部分。我會給他們一個嘗試。 – 2012-02-03 15:09:49

+0

我不知道這是不是用'Border'完成的嗎?這當然是常見的情況,但我從來不需要通用的解決方案。要麼創建兩個'div'元素很容易,要麼更復雜,我創建一個包裝組件。無論如何,我敢打賭,你可以創建一個'ShowOneBorder(Component1,Component2,IModel )',它可以正確地添加它們,並修改一個使用'onConfigure()'可見的。 – jbrookover 2012-02-04 07:54:19

回答

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); 
} } } 

我仍然在尋找一個真正的通用方案,這一點,無論是組合,繼承或裝飾在非空知道ViewX面板。

0

您沒有使用推薦的檢票方式:(

不要扯出來的東西的模型,並推搡到另一個組件:

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。 l除了在組件層次結構的頂層切換「toDisplayWhenObjectIsNull」和「toDisplayWhenObjectIsNotNull」之外。

+0

嗯,謝謝你,但這並沒有回答這個問題:你指出的是什麼*正是*我試圖避免的,因此這個問題... – 2012-02-06 19:25:49

+0

似乎我不明白你的意思是什麼「問題我面對的是,Wicket迫使我完全建立兩個div「 - 爲什麼? – svenmeier 2016-06-22 17:00:29

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"/> 

當然,你應與你的喜好本地化和這樣的定製,但我希望你從所提供的示例中的大圖片。