5

我对 JSF 2 有一个问题。我使用 Mojarra 2.1.14 和 Primefaces 3.1.4

我有一个包含 2 个表单的页面:formAformB。这两个表单在隐藏的输入字段中分别包含 ViewState。

<h:form id="formA" binding="#{sessionBean.formA}">
    <h:commandButton value="formA" action="#{sessionBean.actionA}">
        <f:ajax/>
    </h:commandButton>
</h:form>

<h:form id="formB" binding="#{sessionBean.formB}">
    <h:commandButton value="formB" action="#{sessionBean.actionB}">
        <f:ajax/>
    </h:commandButton>
</h:form>

用户使用 Ajax 操作提交formA 。在 Java 操作中,我显式更新了formAformB(已绑定)。

public void actionA(){
    FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(formA.getClientId());
    FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(formB.getClientId());
    System.out.println("action A!!");
}

public void actionB(){
    System.out.println("action B!!");
}

在 Ajax 响应中有formAformB(元素)的 HTML 代码以及 ViewState。

JSF 更新formAformB的 HTML并设置调用表单的 ViewState:formAformB不包含任何 ViewState。

用户使用 Ajax 操作提交formB 。因为未定义 ViewState,所以 postBack 为 false,并且在 RESTORE 阶段将 renderResponse 设置为 true,跳过了 INVOKE APPLICATION 阶段:未调用该操作。更新响应 VIEW_STATE 后,如果用户提交 formB,则调用该操作。

它是 JSF 2 的错误还是限制?还是我做错了什么?

你可以在 GitHub 上找到一个 maven 项目: https ://github.com/nithril/jsf-multiple-form

在此先感谢您的帮助!

4

2 回答 2

4

您面临的问题与 JSF JavaScript 库的已知问题有关。rendered解决方法是在标签的属性中显式设置另一种形式的客户端 ID f:ajax

<h:form id="formA" binding="#{sessionBean.formA}">
  <h:commandButton value="formA" action="#{sessionBean.actionA}">
    <f:ajax render=":formB @form"/>
  </h:commandButton>
</h:form>

<h:form id="formB" binding="#{sessionBean.formB}">
  <h:commandButton value="formB" action="#{sessionBean.actionB}">
    <f:ajax render=":formA @form"/>
  </h:commandButton>
</h:form>

更多关于这个:

于 2013-02-01T23:04:39.383 回答
2

如果您使用 MyFaces 2.0.x / 2.1.x,还有一个替代技巧可以正确更新表单,添加以下脚本:

window.myfaces = window.myfaces || {};
myfaces.config = myfaces.config || {};
//set the config part
myfaces.config.no_portlet_env = true; 

请参阅JSF Ajax 和多种形式

此选项要好得多,因为您无需担心修复 web 应用程序中使用多个表单的每个地方,只需将其添加到主模板即可。

于 2013-02-02T00:22:28.440 回答