2011-08-19 34 views
12

試圖輸出的項目列表中的DataTable,像這樣:JSF convertDateTime與時區DataTable中

<t:dataTable value="#{mybean.list}" var="item"> 
     <h:column> 
      <h:outputText value="#{item.time}"> 
       <f:convertDateTime pattern="yyyy-MM-dd HH:mm:ssZ" timeZone="#{item.timeZone}" /> 
      </h:outputText> 
     </h:column> 
</t:dataTable> 

它總是在格式化GMT時間。如果我使用字符串常量或不是數據變量的bean(如'#{mybean.timeZone}'),它會按預期工作。

回答

22

不幸的是,這就是<f:xxx>標籤的性質。在構建視圖時,在轉換器實例化的地方構建了一個標籤實例。所有的屬性都被讀取和設置一次。在構建視圖時,#{item}解析爲null(它僅在呈現視圖期間可用),因此timeZone屬性將爲null,然後默認爲UTC。當視圖被渲染時,表格的每一行都重複使用了相同的轉換器實例。

有幾種方法可以解決這個問題。我可以考慮一個自定義轉換器或EL功能。我認爲自定義轉換器畢竟是最好的,因爲它也可以在輸入組件中重用。下面開球例子應該制定出適合你(nullchecks並不再贅述):

@FacesConverter("extendedDateTimeConverter") 
public class ExtendedDateTimeConverter extends DateTimeConverter { 

    @Override 
    public Object getAsObject(FacesContext context, UIComponent component, String value) { 
     setPattern((String) component.getAttributes().get("pattern")); 
     setTimeZone(TimeZone.getTimeZone((String) component.getAttributes().get("timeZone"))); 
     return super.getAsObject(context, component, value); 
    } 

    @Override 
    public String getAsString(FacesContext context, UIComponent component, Object value) { 
     setPattern((String) component.getAttributes().get("pattern")); 
     setTimeZone(TimeZone.getTimeZone((String) component.getAttributes().get("timeZone"))); 
     return super.getAsString(context, component, value); 
    } 

} 

可以用來作爲

<h:outputText value="#{item.time}"> 
    <f:converter converterId="extendedDateTimeConverter" /> 
    <f:attribute name="pattern" value="yyyy-MM-dd HH:mm:ssZ" /> 
    <f:attribute name="timeZone" value="#{item.timeZone}" /> 
</h:outputText> 

這樣的時區是每次解決了轉換器被調用,而不是在它的建設期間。


更新:在OmniFaces <o:converter>正好解決了這個問題,而無需自定義轉換器。

<h:outputText value="#{item.time}"> 
    <o:converter converterId="javax.faces.DateTime" pattern="yyyy-MM-dd HH:mm:ssZ" timeZone="#{item.timeZone}" /> 
</h:outputText>