【问题标题】:Rendering other form by ajax causes its view state to be lost, how do I add this back?通过 ajax 渲染其他表单会导致其视图状态丢失,如何将其添加回来?
【发布时间】: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 错误。我不想用

自动刷新那个 div
jQuery("#mydiv").load(document.location.href);

但在最坏的情况下我会这样做。

【问题讨论】:

    标签: ajax forms jsf jsf-2 viewstate


    【解决方案1】:

    这是处理 ajax 响应的 JSF 自动包含的 jsf.js 库中的一个已知问题。另请参阅JSF spec issue 790,它已在即将发布的 JSF 2.3 中修复。同时,在 JSF 2.0/2.1/2.2 中,您必须在 render 属性内显式指定另一个 &lt;h:form&gt; 的 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.2。让我们再等一两年修复它......
    【解决方案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("&lt;input type='hidden' name='javax.faces.ViewState' /&gt;").val(viewState);
            form.append(input);
        });
    }
    </h:outputScript>
    

    【讨论】:

      猜你喜欢
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-29
      • 2017-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多