猿问

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

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是事先不知道的。另外,这个表单在上下文中也是不可用的。

以上情况有什么解决方案吗?


拉莫斯之舞
浏览 740回答 3
3回答

互换的青春

您可以使用以下脚本修复mojarra2.0/2.1/2.2bug(注意:这在MyFaces中没有显示)。此脚本将创建javax.faces.ViewState表单的隐藏字段,该字段在Ajax更新后没有检索任何视图状态。jsf.ajax.addOnEvent(function(data)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(data.status&nbsp;==&nbsp;"success")&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fixViewState(data.responseXML); &nbsp;&nbsp;&nbsp;&nbsp;}});function&nbsp;fixViewState(responseXML)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;viewState&nbsp;=&nbsp;getViewState(responseXML); &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(viewState)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;document.forms.length;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;form&nbsp;=&nbsp;document.forms[i]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(form.method&nbsp;==&nbsp;"post")&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!hasViewState(form))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;createViewState(form,&nbsp;viewState); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;{&nbsp;//&nbsp;PrimeFaces&nbsp;also&nbsp;adds&nbsp;them&nbsp;to&nbsp;GET&nbsp;forms! &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;removeViewState(form); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}}function&nbsp;getViewState(responseXML)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;updates&nbsp;=&nbsp;responseXML.getElementsByTagName("update"); &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;updates.length;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;update&nbsp;=&nbsp;updates[i]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(update.getAttribute("id").match(/^([\w]+:)?javax\.faces\.ViewState(:[0-9]+)?$/))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;update.textContent&nbsp;||&nbsp;update.innerText; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;null;}function&nbsp;hasViewState(form)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;form.elements.length;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(form.elements[i].name&nbsp;==&nbsp;"javax.faces.ViewState")&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;}function&nbsp;createViewState(form,&nbsp;viewState)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;hidden; &nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hidden&nbsp;=&nbsp;document.createElement("<input&nbsp;name='javax.faces.ViewState'>");&nbsp;//&nbsp;IE6-8. &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch(e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hidden&nbsp;=&nbsp;document.createElement("input"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hidden.setAttribute("name",&nbsp;"javax.faces.ViewState"); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;hidden.setAttribute("type",&nbsp;"hidden"); &nbsp;&nbsp;&nbsp;&nbsp;hidden.setAttribute("value",&nbsp;viewState); &nbsp;&nbsp;&nbsp;&nbsp;hidden.setAttribute("autocomplete",&nbsp;"off"); &nbsp;&nbsp;&nbsp;&nbsp;form.appendChild(hidden);}function&nbsp;removeViewState(form)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;form.elements.length;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;element&nbsp;=&nbsp;form.elements[i]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(element.name&nbsp;==&nbsp;"javax.faces.ViewState")&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;element.parentNode.removeChild(element); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}}只要把它作为<h:outputScript name="some.js" target="head">内部<h:body>错误页。如果不能保证所讨论的页面使用JSF<f:ajax>,这将触发自动包含jsf.js,那么您可能需要添加一个额外的if (typeof jsf !== 'undefined')检查前jsf.ajax.addOnEvent()调用,或显式地将其包含在<h:outputScript&nbsp;library="javax.faces"&nbsp;name="jsf.js"&nbsp;target="head"&nbsp;/>请注意jsf.ajax.addOnEvent只涵盖标准JSF<f:ajax>而不是例如PrimeFaces<p:ajax>或<p:commandXxx>正如他们在封面下使用的那样,jQuery用于这项工作。为了涵盖PrimeFaces Ajax请求,添加以下内容:$(document).ajaxComplete(function(event,&nbsp;xhr,&nbsp;options)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(typeof&nbsp;xhr.responseXML&nbsp;!=&nbsp;'undefined')&nbsp;{&nbsp;//&nbsp;It's&nbsp;undefined&nbsp;when&nbsp;plain&nbsp;$.ajax(),&nbsp;$.get(),&nbsp;etc&nbsp;is&nbsp;used&nbsp;instead&nbsp;of&nbsp;PrimeFaces&nbsp;ajax. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fixViewState(xhr.responseXML); &nbsp;&nbsp;&nbsp;&nbsp;}}更新如果使用JSF实用程序库OmniFaces,很高兴知道,自1.7之后,上述内容已经成为OmniFaces的一部分。只是在<h:body>..另见陈列柜.<h:body> &nbsp;&nbsp;&nbsp;&nbsp;<h:outputScript&nbsp;library="omnifaces"&nbsp;name="fixviewstate.js"&nbsp;target="head"&nbsp;/> &nbsp;&nbsp;&nbsp;&nbsp;...</h:body>

UYOU

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

相关分类

Java
我要回答