渲染其他forms的Ajax导致其视图状态丢失,我该如何添加回来?

我有

<h:form> <h:commandLink action="#{my_fake_ajax_link}"> <h:outputText value="Link" /> <f:ajax render=":mydiv" /> </h:commandLink> </h:form> <h:panelGroup layout="block" id="mydiv"> <h:form> <h:commandLink action="#{mybean.delete(0)}"> <h:outputText value="Here" /> <f:ajax render="@form" /> </h:commandLink> </h:form> </h:panelGroup> 

当我点击一次“my_fake_ajax_link”,那么我必须点击两次“删除”链接。 这只是一个例子。 我没有这个真实的案例。 我在一个页面上有多个表单,我不能只用一个表单添加所有的表单。

我检查了问题是什么,它是:

  • 当你点击“my_fake_ajax_link”时, mydiv像使用ajax一样刷新。
  • ajax刷新表单的ViewState丢失。

我如何添加ViewState? 我怎样才能使它不工作,只使用一种forms? 这看起来像一个JSF错误给我。 我不想自动刷新该div

 jQuery("#mydiv").load(document.location.href); 

但我会在最糟的情况下成为可能的。

这是JSF自动包含的jsf.js库中的一个已知问题,它处理ajax响应。 另请参阅即将发​​布的JSF 2.3中修复的JSF规范问题790 。 与此同时,在JSF 2.0 / 2.1 / 2.2中,您必须在render属性中明确指定另一个<h:form>的ID,以触发视图状态的正确添加。

 <h:form> <h:commandLink action="#{my_fake_ajax_link}"> <h:outputText value="Link" /> <f:ajax render=":mydiv :mydivForm" /> </h:commandLink> </h:form> <h:panelGroup layout="block" id="mydiv"> <h:form id="mydivForm"> <h:commandLink action="#{mybean.delete(0)}"> <h:outputText value="Here" /> <f:ajax render="@form" /> </h:commandLink> </h:form> </h:panelGroup> 

不,这不会导致ajax响应中的任何开销或标记重复。 或者,使用OmniFaces fixviewstate.js

也可以看看:

  • JSF 2.0中的通信 – 包含另一个表单的内容的Ajax呈现
  • h:commandButton / h:commandLink不能在第一次点击时使用,只能在第二次点击时使用

解决方法:

首先,您需要为发送ajax请求的button设置一个onevent处理程序:

 <h:form id="newComment"> <h:commandButton id="saveNewComment" action="#{postBean.actionSaveNewCommentAjax}" value="#{rb['speichern']}"> <f:ajax execute="@form" render=":commentsBox" onevent="function(data) { fixOtherFormsViewState(data, 'newComment') }" /> </h:commandButton> </h:form> 

然后你需要声明这个JavaScript方法,将采取正确的viewState值,并将其添加到所有没有它的窗体:

 <h:outputScript> function fixOtherFormsViewState(data, goodFormId) { if (data.status != "success") { return; } var viewState = jQuery("#" + goodFormId + " input[name='javax.faces.ViewState']").val(); jQuery("form:not(:contains(input[name='javax.faces.ViewState']))").each(function (idx, elem) { var form = jQuery(elem); var input = jQuery("&lt;input type='hidden' name='javax.faces.ViewState' /&gt;").val(viewState); form.append(input); }); } </h:outputScript>