在模型视图更新之前,转换器是否始终运行?

时间:2013-01-21 15:24:26

标签: jsf-2

示例:

<h:form>
    <h:selectOneMenu value="#{bean.timezone}>
        <f:selectItems value="#{bean.availableTimezones} ... >
        <f:ajax render="currenttime" />
    </h:selectOneMenu>
</h:form>

<h:form id="currenttime">
    <h:outputText value="#{bean.currentTime}" >
        <f:convertDateTime dateStyle="short" type="both" timeZone="#{bean.timezone}" />
    </h:outputText>
</h:form>

<!-- bean.currentTime is of type 'Date' -->

在示例中,更改时区应使currenttime中的文本显示在适当的时区。但事实并非如此。

我认为这是因为转换器是在“应用请求”阶段计算的,所选时区的值是在“更新模型”阶段更新的。

我是对的吗? 我不应该使用转换器吗?

谢谢!

1 个答案:

答案 0 :(得分:6)

导致您的具体问题是因为<f:convertDateTime>在视图构建期间初始化,而不是在视图渲染时间(exactly like JSTL and so on)期间。实际上,这在更新模型值阶段之前运行很远,因此在视图渲染时间内转换器不会使用用户提交的时区进行设置。

此问题与以下答案中的答案基本相同:

其中一种方法是将转换器实例作为bean属性进行管理和绑定。

private DateTimeConverter converter;

@PostConstruct
public void init() {
    converter = new DateTimeConverter();
    converter.setDateStyle("short");
    converter.setType("both");
}

public DateTimeConverter getDateTimeConverter() {
    converter.setTimeZone(timezone);
    return converter;
}

使用

<h:outputText value="#{bean.currentTime}" >
    <f:converter binding="#{bean.dateTimeConverter}" />
</h:outputText>

另一种方法是使用OmniFaces <o:converter来支持转换器属性的rendertime评估:

<h:outputText value="#{bean.currentTime}" >
    <o:converter converterId="javax.faces.DateTime" dateStyle="short" type="both" timeZone="#{bean.timezone}" />
</h:outputText>