1

考虑以下代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:o="http://omnifaces.org/ui">

    <f:metadata>
        <o:viewParam name="selected" value="#{testBacking.selected}" >
        </o:viewParam>
    </f:metadata>

    <h:head>
        <title>
            title
        </title>

    </h:head>

    <h:body>
        <o:form includeViewParams="true">
            <h:commandButton action="#{testBacking.go()}" value="go">
                <f:ajax execute="@all" render="@all"/>
            </h:commandButton>
        </o:form>
    </h:body>

</html>

动作方法:

public void go() {
    System.out.println("go() is called");

    Collection<UIViewParameter> viewParams = ViewMetadata.getViewParameters(FacesContext.getCurrentInstance().getViewRoot());

    for (UIViewParameter viewParam : viewParams) {
        System.out.println(viewParam.getName() +" = "+ viewParam.getValue());
    }
}

action 方法返回正确的 viewParam 名称,但该值始终为 null。如果这是预期的行为,那么<o:form includeViewParams="true">在实际使用中有何帮助?

我正在使用 Mojarra 2.1.12 和 Omnifaces 1.1。

4

1 回答 1

4

您的 bean 显然是请求范围的。旨在与视图范围的bean<o:viewParam>结合使用,只是因为它可以防止模型在每次回发到同一视图时一次又一次地转换/验证/更新,即使它已经在初始请求期间完成并且仍然作为属性存在视图范围的 bean。当模型绑定到基于 DB 调用执行工作的昂贵转换器时,这会提高整体性能。展示示例也清楚地表明了这一点。

为了实现这一点,<o:viewParam>在任何回发期间基本上都会跳过这个模型转换/验证/更新作业。然而,在每个请求上都会新创建一个请求范围的 bean,因此初始模型值在每次回发时都会丢失,并且由于<o:viewParam>根本没有设置的设计。

您可以通过将 bean 放置在视图范围内来解决此问题,或者仅使用标准<f:viewParam>来解决。

至于<o:form includeViewParams="true">,这仅对同步回发有用。如果您删除,<f:ajax>那么您将看到它是如何有用的。没有includeViewParams="true"URL 就变成了没有 view 参数的那个,即没有?selected=somevalue,因此它变得无法添加书签。这与 没有严格的关系<o:viewParam>,它与 结合起来效果很好<f:viewParam>

于 2012-09-28T13:00:05.087 回答