2013-07-15 85 views
1

表單處理我有一個可以描述的模型如下:與繼承

http://aoeu.se/so/animal-dog-cat.png

(極度簡化我的實際類有左右各一零二零年更多的領域。)

我有持久性全部解決了,我現在試圖創建一個表單,用戶應該能夠創建這些類(狗和貓)的對象。

我想它大致如下所示:(我已經有HTML和實​​施輸入字段的啓用/禁用)

http://aoeu.se/so/new-animal-form.png

我的問題:我如何最好地實現表單處理?由於模型對象的類型取決於第一個Dog/Cat的選擇,因此我不瞭解如何直接使用PropertyModels等。

如果Wicket保證字段處理的順序與它們在網頁中出現的順序相同,那麼我想我可以在處理動物類型輸入時創建模型對象(因爲它是第一個表單組件),並讓其餘字段使用PropertyModel。

+1

您可以通過Ajaxifying它並使用onChange事件來切換形模型分開的形式存在,例如其餘的動物類型選擇一個符合所選類型(在需要的地方複製數據)... – Nicktar

+0

沒錯。那將是另一種選擇。雖然會有很多複製。但也許這是最好的解決方案。 – aioobe

+0

如果你想爲模型使用組合(比如CatModel和DogModel都包含AnimalModel和委託方法),你可以將「繼承」部分移動... – Nicktar

回答

2

首先,您應該考慮將動物類型選擇與表格的其餘部分分開,因爲如果用戶在輸入某些數據後決定更改類型,則需要放棄某些條目。這可以通過將這部分表單渲染並使用onChange事件來清理數據並切換模型來實現。

當你這樣做的時候,你可能想考慮從繼承轉換到合成,以避免複製數據。我不知道這是否仍然與持久性策略兼容,但是您可以將完成的數據複製到持久層。

例如,當您CatModel沒有從AnimalModel繼承而是包含這樣的AnimalModel:

public class CatModel { 

    private final AnimalModel parent; 
    private String meowingSound; 

    public CatModel(AnimalModel parent) { 
     this.parent = parent; 
    } 

    public int getNumLegs() { 
     return parent.getNumLegs(); 
    } 

    public void setNumLegs(int numLegs) { 
     parent.setNumLegs(numLegs); 
    } 

    public String getMeowingSound() { 
     return meowingSound; 
    } 

    public void setMeowingSound(String meowingSound) { 
     this.meowingSound = meowingSound; 
    } 

    public AnimalModel getParent() { 
     return parent; 
    } 

} 

(接口跳過)

你可以採取AnimalModel從(同樣構造)DogModel初始化您的CatModels'繼承的'數據。

public class AnimalModel { 

    private int numLegs; 

    public int getNumLegs() { 
     return numLegs; 
    } 

    public void setNumLegs(int numLegs) { 
     this.numLegs = numLegs; 
    } 
} 

AnimalModel爲了完整性......

+0

我的模型類有很多虛擬方法和依賴於繼承的內部類,所以更改爲合成不幸是不是一種選擇。 (除非你在談論一些輔助類,但是我將不得不在兩個不同的類中複製每個字段。) – aioobe

+0

我認爲你必須堅持複製。我們有意使用非常不同類型的模型。對我來說,一個模型(對於wicket而言)只不過是一個數據容器。一些成員,getter,setter,可能有些代碼可以與daos,equals,hashCode進行交談,而這對大多數情況來說都是如此。 – Nicktar

+0

在我決定創建一個Web前端之前,我很早就設計了這些類,並且我不願意切換到[貧血域模型](http://en.wikipedia.org/wiki/Anemic_domain_model)。 – aioobe