简体   繁体   English

在p:commandButton中刷新两次,竞争状态为oncomplete

[英]Twice refreshed in p:commandButton, race condtition with oncomplete

I'm executing the server action with p:commandButton . 我正在使用p:commandButton执行服务器操作。 After those action is completed, I'm refreshing the form (to show hidden fields) and I show dialog. 完成这些操作后,我将刷新表单(以显示隐藏字段)并显示对话框。 I've tried also to refresh only the panels with hidden buttons, but the effect was the same: 我也尝试过只刷新带有隐藏按钮的面板,但是效果是一样的:

There is second refresh launched, after I call dialog.show(). 我调用dialog.show().之后,启动了第二次刷新dialog.show(). The problem is, that the widgets defined inside the dialog and the dialog itself is not existing in the moment! 问题在于,对话框内部定义的小部件和对话框本身目前不存在! So, when my JavaScript code runs too fast, before the post with update of the dialog finishes, I'm getting an exception, because the object I want to modify doesn't exist in DOM tree. 因此,当我的JavaScript代码运行得太快时,在对话框更新后的帖子完成之前,我得到了一个例外,因为要修改的对象在DOM树中不存在。

So my first question, is it possible to avoid such situation and second refresh, can't the dialog be refreshed along with page? 所以我的第一个问题是,是否有可能避免这种情况和第二次刷新,对话框不能随页面一起刷新吗?

And second, if the first can't be answered, how can I launch my code after those second post finishes? 第二,如果无法回答第一个问题,那么这些第二篇文章完成之后 ,如何启动我的代码? I need simply a callback when refreshing of the dialog component will be completed, and than run my operations. 在完成对话框组件的刷新时,我只需要一个回调即可,然后运行我的操作。

    <p:commandButton id="doTask" value="Do task" widgetVar="doTaskButton"
        action="#{service.doTask}" update="@form"
        onclick="disableMainButtons()"
        oncomplete="async.showAsyncDialog()" />

The HTTP sequence: HTTP序列:

// button click
POST http://localhost:9080/myapp/order.xhtml 200 OK
// oncomplete launches dialog.show()
// I receive answer from COMET before the dialog to display it is shown
POST http://localhost:9080/myapp/channel/async 200 OK
// refresh triggered by dialog.show(), only now the dialog is shown and it's widgets are rendered
POST http://localhost:9080/myapp/order.xhtml 200 OK

The workaround, that isn't beautiful from programming point of view is to check if the dialog is rendered and if not, delay my procedure. 从编程的角度来看,这种解决方法并不美观,它是检查对话框是否已渲染,如果没有渲染,请延迟我的过程。 In case the dialog is still not rendered, delay once again etc. 如果对话框仍未呈现,请再次延迟等。

waitForDialogRendered: function() {
    var visible = asyncDialog.jq.css('visibility') == 'visible';
    if (!visible) {
        setTimeout(waitForDialogRendered, 250);
        return;
    }
    runComet();
}

Not that asyncDialog.jq.is(':visible') returns true even if dialog is not visible for user! 即使对话框对用户不可见,也不是asyncDialog.jq.is(':visible')返回true

Still, I'd be happier without the need to write such code. 不过,无需编写此类代码我会更开心。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM