2011-04-11 34 views
8

將datacolumn綁定到數據源中可能存在或可能不存在的屬性的最佳方法是什麼?JSF和表達式語言:僅在綁定屬性存在時

例如,當您有一個類層次結構,其中一些子類可能是具有該屬性的子類型時,會發生這種情況。數據源包含各種子類型。

<DataColumn outputText="#{item.property}" /> 

當屬性不​​存在於其中一個子類中時,總是產生PropertyNotFoundException。我不希望將該屬性包含在基類中,因爲它不應該根據業務規則存在。

你會如何解決這個問題?

回答

2

我認爲在這種情況下最好的方法是爲視圖層創建一個具有所有必要字段的自定義實體,並將要顯示的項目轉換爲它。

0

爲什麼不具有基類的布爾屬性,告訴您在子類中是否具有實際屬性。這樣,你可以很容易地使用三元運算在EL表達式,像這樣:

<DataColumn outputText="#{item.hasProperty ? item.property : 'I don't have this property.'}" /> 

如果EL懶洋洋地計算表達式這可以工作,但我不知道,不能馬上檢查。但無論如何,這是一個想法。

7

如果不更改課程,最好的辦法是在EL中做一種instanceof。您可以通過檢查EL中的Object#getClass(),然後Class#getName()Class#getSimpleName()獲得的(簡單)類名來完成此操作。

假設與物業類具有完全限定名com.example.SubItem,這裏有一個例子:根據此模型

<h:outputText value="#{item.property}" rendered="#{item.class.name == 'com.example.SubItem'}" /> 

<h:outputText value="#{item.property}" rendered="#{item.class.simpleName == 'SubItem'}" /> 
+0

我嘗試使用#{item.class}時遇到了問題,但與#{item.getClass()}配合良好 – 2012-07-06 13:02:24

+0

任何想法如果在事先不知道類的情況下該怎麼做? – 2014-07-09 19:52:03

0

我想你可能想要做一個在支持bean中做了很多工作,而不是試圖使其在實際的JSF頁面上工作。

您可以將表格只是綁定到bean作爲

<h:dataTable binding="#{myBean.dataTable}" /> 

//BEAN 
HtmlDataTable dataTable; 

public DataTable getDataTable() 
{ 
    dataTable = new HtmlDataTable(); //etc... 
    //add the columns here based on the logic in code 
} 

,然後實際做豆腐內呈現動態地添加成分等..如果你正在尋找模型分離和你需要頁面成爲一個非常受控制的bean,那麼上面的答案實際上就是你所追求的。

或者如建議的那樣,只需使用呈現的屬性並檢查類名(注意空指針)。我經常做這兩件事,這實際上取決於我在實際的JSF中會有多少複雜的布爾邏輯。

4

作爲在EL中提供instanceof功能的替代方法,您可以考慮將isInstanceOf()方法添加到ApplicationScoped bean。我使用類似:

@ManagedBean(name="app") 
@ApplicationScoped 
public class ApplicationController implements Serializable { 
    public boolean isInstanceOf(Object o, String className) throws ClassNotFoundException { 
     return Class.forName(className).isInstance(o); 
    } 
} 

然後我把它從EL這樣的:

<... rendered="#{app.isInstanceOf(someObject, 'java.lang.Object')}"> 

有了一些調整,這種想法可以推廣到方便調用從EL任何靜態方法。