【问题标题】:Cannot show dialog in Primefaces RequestContext.execute() call无法在 Primefaces RequestContext.execute() 调用中显示对话框
【发布时间】:2013-04-23 15:49:50
【问题描述】:

我有一个选项卡视图,每当用户选择该选项卡时,我想在其中刷新一个特定选项卡的内容。我还希望在刷新选项卡时弹出模式对话框。

这是带有 tabChange ajax 事件处理程序的 tabView

<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 控制台中没有错误。

为什么当remoteCommand 被RequestContext.execute() 触发时statusDialog 不显示,我怎样才能让它出现?我什至尝试将 statusDialog.show() 添加到 execute() 但它没有帮助。

【问题讨论】:

  • 你能试试&lt;p:ajax event="tabChange" listener="#{bean.tabChangeListener}" oncomplete="statusDialog.show();"&gt;&lt;/p:ajax&gt;吗?
  • 这将导致 statusDialog 显示在所有选项卡更改上。我只希望它在选择一个特定选项卡时显示。

标签: jsf jsf-2 primefaces


【解决方案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 调用完成并在我的 refresh() 事情正在进行时调用了 statusDialog.hide()。上面的 JS 代码维护了多少 Ajax 调用正在进行的计数器,并且只有在所有调用完成后才会隐藏状态对话框。现在按预期工作!

【讨论】:

    【解决方案2】:

    如果您想在更改特定选项卡时显示对话框,您可以通过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();
        } 
    }
    

    或者不同的方法是定义一个值并使用p:dialogvisible属性:

    public void tabChangeListener(TabChangeEvent event) {
            if ( event.getTab().getId().equalsIgnoreCase("tab2") ) {
                        this.condition=true;
            }
        }
    

    还有&lt;p:dialog visible="#{bean.condition}"/&gt;。也许你需要专注于你的第一种方法,你可以给p:dialog一个ID并通过p:remoteCommand更新它:

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

    不要忘记在 p:remoteCommand 的更新属性中提供对话框的确切客户端 ID。

    【讨论】:

    • 不错的解决方法,但它仍然不起作用。控制台中没有错误。
    • 能否添加警报(1); js函数的if case里面?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-21
    • 1970-01-01
    • 2013-02-08
    相关资源
    最近更新 更多