通过 ajax 渲染其他表单会导致其视图状态丢失,如何将其添加回来?
Posted
技术标签:
【中文标题】通过 ajax 渲染其他表单会导致其视图状态丢失,如何将其添加回来?【英文标题】:Rendering other form by ajax causes its view state to be lost, how do I add this back? 【发布时间】:2011-12-10 01:50:11 【问题描述】:我有
<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?我怎样才能使它工作而不使用仅一种形式?对我来说,这看起来像是一个 JSF 错误。我不想用
自动刷新那个 divjQuery("#mydiv").load(document.location.href);
但在最坏的情况下我会这样做。
【问题讨论】:
【参考方案1】:这是处理 ajax 响应的 JSF 自动包含的 jsf.js
库中的一个已知问题。另请参阅JSF spec issue 790,它已在即将发布的 JSF 2.3 中修复。同时,在 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
。
另见:
Communication in JSF 2.0 - Ajax rendering of content which contains another form h:commandButton/h:commandLink does not work on first click, works only on second click【讨论】:
非常感谢!!!我在谷歌上没有找到那个链接..即使经过长时间的搜索...... 很遗憾这还没有进入 JSF 2.2。让我们再等一两年修复它...... @mel:OmniFaces 救援:showcase.omnifaces.org/scripts/FixViewState【参考方案2】:解决方法:
首先,您需要为发送 ajax 请求的按钮设置一个 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("<input type='hidden' name='javax.faces.ViewState' />").val(viewState);
form.append(input);
);
</h:outputScript>
【讨论】:
以上是关于通过 ajax 渲染其他表单会导致其视图状态丢失,如何将其添加回来?的主要内容,如果未能解决你的问题,请参考以下文章
JSF Ajax 渲染使用 Jquery Mobile 丢失 CSS
(火狐浏览器)前端以FormData类形成表单(含文件),通过ajax提交,PHP后端iconv()报“文件名含有非法字符”且POST中的‘Ttitle’丢失