为了账号安全,请及时绑定邮箱和手机立即绑定

h:CommandButton/h:命令链接在第一次单击时不起作用,仅在第二次单击时才有效。

h:CommandButton/h:命令链接在第一次单击时不起作用,仅在第二次单击时才有效。

拉莫斯之舞 2019-06-26 13:52:19
h:CommandButton/h:命令链接在第一次单击时不起作用,仅在第二次单击时才有效。我们有一个Ajax导航菜单,它更新动态包含。包含文件有各自的表单。<h:form>     <h:commandButton value="Add" action="#{navigator.setUrl('AddUser')}">         <f:ajax render=":propertiesArea" />     </h:commandButton></h:form><h:panelGroup id="propertiesArea" layout="block">     <ui:include src="#{navigator.selectedLevel.url}" /></h:panelGroup>它工作正常,但包含文件中的任何命令按钮在第一次单击时都不能工作。它只适用于第二次点击和重复。我发现了这个问题未调用的命令Button/CommandLink/ajax操作/侦听器方法或未更新的输入值我的问题在第9点中有描述,我知道我需要显式地包括<h:form>在包含在<f:ajax render>来解决这个问题。<f:ajax render=":propertiesArea :propertiesArea:someFormId" />然而,在我的例子中,表单ID是事先不知道的。另外,这个表单在上下文中也是不可用的。以上情况有什么解决方案吗?
查看完整描述

3 回答

?
互换的青春

TA贡献1797条经验 获得超6个赞

您可以使用以下脚本修复mojarra2.0/2.1/2.2bug(注意:这在MyFaces中没有显示)。此脚本将创建javax.faces.ViewState表单的隐藏字段,该字段在Ajax更新后没有检索任何视图状态。

jsf.ajax.addOnEvent(function(data) {
    if (data.status == "success") {
        fixViewState(data.responseXML);
    }});function fixViewState(responseXML) {
    var viewState = getViewState(responseXML);

    if (viewState) {
        for (var i = 0; i < document.forms.length; i++) {
            var form = document.forms[i];

            if (form.method == "post") {
                if (!hasViewState(form)) {
                    createViewState(form, viewState);
                }
            }
            else { // PrimeFaces also adds them to GET forms!
                removeViewState(form);
            }
        }
    }}function getViewState(responseXML) {
    var updates = responseXML.getElementsByTagName("update");

    for (var i = 0; i < updates.length; i++) {
        var update = updates[i];

        if (update.getAttribute("id").match(/^([\w]+:)?javax\.faces\.ViewState(:[0-9]+)?$/)) {
            return update.textContent || update.innerText;
        }
    }

    return null;}function hasViewState(form) {
    for (var i = 0; i < form.elements.length; i++) {
        if (form.elements[i].name == "javax.faces.ViewState") {
            return true;
        }
    }

    return false;}function createViewState(form, viewState) {
    var hidden;

    try {
        hidden = document.createElement("<input name='javax.faces.ViewState'>"); // IE6-8.
    } catch(e) {
        hidden = document.createElement("input");
        hidden.setAttribute("name", "javax.faces.ViewState");
    }

    hidden.setAttribute("type", "hidden");
    hidden.setAttribute("value", viewState);
    hidden.setAttribute("autocomplete", "off");
    form.appendChild(hidden);}function removeViewState(form) {
    for (var i = 0; i < form.elements.length; i++) {
        var element = form.elements[i];
        if (element.name == "javax.faces.ViewState") {
            element.parentNode.removeChild(element);
        }
    }}

只要把它作为<h:outputScript name="some.js" target="head">内部<h:body>错误页。如果不能保证所讨论的页面使用JSF<f:ajax>,这将触发自动包含jsf.js,那么您可能需要添加一个额外的if (typeof jsf !== 'undefined')检查前jsf.ajax.addOnEvent()调用,或显式地将其包含在

<h:outputScript library="javax.faces" name="jsf.js" target="head" />

请注意jsf.ajax.addOnEvent只涵盖标准JSF<f:ajax>而不是例如PrimeFaces<p:ajax><p:commandXxx>正如他们在封面下使用的那样,jQuery用于这项工作。为了涵盖PrimeFaces Ajax请求,添加以下内容:

$(document).ajaxComplete(function(event, xhr, options) {
    if (typeof xhr.responseXML != 'undefined') { // It's undefined when plain $.ajax(), $.get(), etc is used instead of PrimeFaces ajax.
        fixViewState(xhr.responseXML);
    }}

更新如果使用JSF实用程序库OmniFaces,很高兴知道,自1.7之后,上述内容已经成为OmniFaces的一部分。只是在<h:body>..另见陈列柜.

<h:body>
    <h:outputScript library="omnifaces" name="fixviewstate.js" target="head" />
    ...</h:body>


查看完整回答
反对 回复 2019-06-26
?
UYOU

TA贡献1878条经验 获得超4个赞

关于使用js代码,你能更具体一点吗?我在richFaces 4.5.13中使用了一个简单的脚本标记,它在命令按钮(“h:”或“a4j:”)上的结果是相同的(必须单击两次);您也没有提到jQuery/richFaces版本。

查看完整回答
反对 回复 2019-06-26
  • 3 回答
  • 0 关注
  • 739 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号