无法在Primefaces RequestContext.execute()调用中显示对话框

时间:2013-04-23 15:49:50

标签: jsf jsf-2 primefaces

我有一个tabview,我想在用户选择该标签时刷新一个特定标签的内容。我还希望在刷新选项卡时弹出模态对话框。

这是tabView with tabChange ajax事件处理程序

<p:dialog widgetVar="statusDialog" modal="true" draggable="false" minimizable="false" appendToBody="true"   closable="false" header="Processing..." resizable="false" maximizable="false">  
     <p:graphicImage library="assets" name="ajax-loader.gif"></p:graphicImage> 
</p:dialog>

<p:tabView id="tabview" orientation="top" dynamic="false">
    <p:ajax event="tabChange" listener="#{bean.tabChangeListener}"></p:ajax>
    <p:tab title="tab1">
        <ui:include src="/WEB-INF/views/tab1.xhtml"/>
    </p:tab>
    <p:tab title="tab2">
        <p:remoteCommand actionListener="#{bean.refreshData}" update="someTab2ElementID" name="refresh" global="true" onstart="statusDialog.show()" oncomplete="statusDialog.hide()"/>
        <ui:include src="/WEB-INF/views/tab2.xhtml"/>
    </p:tab>
</p:tabView>

这是tabChangeListener:

public void tabChangeListener(TabChangeEvent event) {
    if ( event.getTab().getId().equalsIgnoreCase("tab2") ) {
                RequestContext.getCurrentInstance().execute("refresh()");
    }
}

正在按预期调用刷新remoteCommand,但我的statusDialog从未显示过。如果按钮触发相同的remoteCommand,则会出现statusDialog。 JavaScript控制台中没有错误。

为什么在RequestContext.execute()触发remoteCommand时不显示statusDialog,如何显示?我甚至尝试将statusDialog.show()添加到execute()但它没有帮助。

2 个答案:

答案 0 :(得分:1)

我明白了。这是解决方案:

<h:outputScript>
var blockCount=0;
function showStatus() {
 if (blockCount==0) statusDialog.show();
 blockCount++;
};
function hideStatus() {
 blockCount--;
 if (blockCount==0) statusDialog.hide();
};
</h:outputScript>

<p:ajaxStatus onstart="showStatus();" onsuccess="hideStatus();" onerror="blockCount=0;statusDialog.hide();errorDialog.show();"/>  

<p:remoteCommand actionListener="#{bean.refreshData}" update="someTab2ElementID" name="refresh" global="true" onstart="showStatus()" oncomplete="hideStatus()"/>

显然我的状态对话框没有显示的原因是另一个Ajax调用完成并调用statusDialog.hide()而我的refresh()事情正在进行中。上面的JS代码维护着一个正在进行的Ajax调用的计数器,并且只会在所有调用完成后隐藏状态对话框。现在按预期工作!

答案 1 :(得分:0)

如果要在更改特定选项卡时显示对话框,可以通过ajax响应添加回调参数来通知js函数,选项卡选择控件是否为2:

public void tabChangeListener(TabChangeEvent event) {
    if ( event.getTab().getId().equalsIgnoreCase("tab2") ) {
                RequestContext.getCurrentInstance().addCallbackParam("index", 2);
    }
}

并使用:

 <p:ajax event="tabChange" listener="#{bean.tabChangeListener}"
     oncomplete="showOrNot(xhr,status,args)"></p:ajax>

这将调用js函数,它将控制更改的选项卡是否为2:

function showOrNot(xhr,status,args) {
    if(args.index==2) {
        statusDialog.show();
    } 
}

或者不同的方法是定义一个值并使用visible的{​​{1}}属性:

p:dialog

public void tabChangeListener(TabChangeEvent event) { if ( event.getTab().getId().equalsIgnoreCase("tab2") ) { this.condition=true; } } 。也许您需要专注于第一种方法,并且可以为<p:dialog visible="#{bean.condition}"/>提供ID并通过p:dialog进行更新:

p:remoteCommand

不要忘记在<p:remoteCommand actionListener="#{bean.refreshData}" update="someTab2ElementID dialog" name="refresh" global="true" onstart="statusDialog.show()" oncomplete="statusDialog.hide()"/> 的更新属性中提供对话框的确切客户端ID。