按PrimeFaces p:commandButton时事件的执行顺序

Abh*_*hay 33 jsf action primefaces jsf-2 commandbutton

我试图执行一个JSF2 bean方法,并在完成单击PrimeFaces的方法后显示一个对话框<p:commandButton>.

<p:commandButton id="viewButton" value="View"
    actionlistener="#{userBean.setResultsForSelectedRow}" ajax="false"
    update=":selectedRowValues"
    oncomplete="PF('selectedRowValuesDlg').show()">
</p:commandButton>
Run Code Online (Sandbox Code Playgroud)
<p:dialog id="selectedRowValues" widgetVar="selectedRowValuesDlg" dynamic="true">
    <h:outputText value="#{userBean.selectedGroupName}" />
</p:dialog>
Run Code Online (Sandbox Code Playgroud)

当我单击命令按钮时,bean动作侦听器方法setResultsForSelectedRow正确执行,但在方法完成时它不显示对话框.如果我删除actionlistener,它会显示对话框.我不知道出了什么问题.

事件的执行顺序是什么?是否有可能执行actionlisteneroncomplete同步?

Bal*_*usC 129

因为你使用它失败了ajax="false".这将激活这反过来又导致重新加载整个页面的完整同步请求,导致oncomplete永远不会被解雇,以(注意,所有其他的Ajax相关的属性,如process,onstart,onsuccess,onerror并且update也从来没有发射).

当你移除它时,actionListener它也是不可能的.它应该以同样的方式失败.也许你也ajax="false"没有真正理解你在做什么,也沿着它移除了.删除ajax="false"应该确实达到所需的要求.


还可以同时执行actionlistener和oncomplete吗?

不可以.只能在动作侦听器之前之后触发脚本.您可以使用onclick在单击时触发脚本.您可以使用onstart在即将发送ajax请求时触发脚本.但他们永远不会同时被解雇.顺序如下:

  • 用户单击客户端中的按钮
  • onclick 执行JavaScript代码
  • JavaScript根据process当前的HTML DOM树准备ajax请求
  • onstart 执行JavaScript代码
  • JavaScript从客户端向服务器发送ajax请求
  • JSF检索ajax请求
  • JSF基于JSF组件树处理请求生命周期 process
  • actionListener 执行JSF支持bean方法
  • action 执行JSF支持bean方法
  • JSF基于update当前的JSF组件树准备ajax响应
  • JSF从服务器向客户端发送ajax响应
  • JavaScript检索ajax响应
    • 如果HTTP响应状态为200,onsuccess则执行JavaScript代码
    • 否则,如果HTTP响应状态为500,onerror则执行JavaScript代码
  • JavaScript update基于ajax响应和当前的HTML DOM树执行
  • oncomplete 执行JavaScript代码

请注意,之后update执行,因此如果您使用或显示对话框,则它仍可能显示旧内容而不是更新内容,这对用户体验来说很差.然后,您最好使用它来显示对话框.另请注意,您最好使用而不是在打算执行业务操作时使用. actionListeneronclickonstartoncompleteactionactionListener

也可以看看:


Fre*_*ngs 8

我只是喜欢获得像BalusC这样的信息 - 他非常友好地帮助那些有这么好信息的人,我认为他的话是福音,但我无法用这种事件来解决同样的时机问题.我的项目中的问题.由于BalusC在这里提供了一个很好的一般参考,我甚至收藏了书签,我想我会在同一个地方为一些高级计时问题捐赠我的解决方案,因为它确实解决了原始海报的时间问题.我希望这段代码可以帮助某人:

        <p:pickList id="formPickList" 
                    value="#{mediaDetail.availableMedia}" 
                    converter="MediaPicklistConverter" 
                    widgetVar="formsPicklistWidget" 
                    var="mediaFiles" 
                    itemLabel="#{mediaFiles.mediaTitle}" 
                    itemValue="#{mediaFiles}" >
            <f:facet name="sourceCaption">Available Media</f:facet>
            <f:facet name="targetCaption">Chosen Media</f:facet>
        </p:pickList>

        <p:commandButton id="viewStream_btn" 
                         value="Stream chosen media" 
                         icon="fa fa-download"
                         ajax="true"
                         action="#{mediaDetail.prepareStreams}"                                              
                         update=":streamDialogPanel"
                         oncomplete="PF('streamingDialog').show()"
                         styleClass="ui-priority-primary"
                         style="margin-top:5px" >
            <p:ajax process="formPickList"  />
        </p:commandButton>
Run Code Online (Sandbox Code Playgroud)

该对话框位于此表单之外的XHTML的顶部,它在对话框中嵌入了自己的一个表单以及一个数据表,该数据表包含用于流媒体的其他命令,当对话框为对话时,所有这些命令都需要准备好并准备就绪呈现.您可以使用相同的技术来执行下载自定义文档之前需要准备的文档,然后通过对话框中的fileDownload按钮将这些文档传输到用户的计算机.

正如我所说的,这是一个更复杂的例子,但它击中了你的问题和我的所有高点.单击命令按钮时,结果是首先确保使用pickList的结果更新辅助bean,然后告诉辅助bean根据用户在选择列表中的选择为用户准备流,然后更新控件带有更新的动态对话框,然后显示准备好供用户开始流式传输其内容的对话框.

它的诀窍是使用BalusC的主命令顺序为主命令按钮然后添加该<p:ajax process="formPickList" />位以确保它首先被执行 - 因为没有正确的事情发生,除非pickList首先更新了支持bean(在我之前没有发生的事情)添加它).所以,是的,那个命令按钮因为你可以影响以前的,待定的和当前的组件以及支持bean而摇滚 - 但是有时候相互关联所有这些组件的时机并不容易.

快乐的编码!