2011-08-19 36 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>