Hey, 2008/8/8 <[EMAIL PROTECTED]>: > How to reproduce: > Slot code has to delete something from DOM page (for example table from > root) and then create something on it. > You should activate slot reaction several times simultaneously (for > example rapidly clicking the button that in connected to a slot many times). > Sometimes the above error arises, and after that you have nothing to do > besides reloading web-page (and application) as it won't work. > > Here's workaround that fixes this problem: > > Index: head/src/wt-2.1.5/src/web/skeleton/Wt.js > =================================================================== > --- head/src/wt-2.1.5/src/web/skeleton/Wt.js (revision 776) > +++ head/src/wt-2.1.5/src/web/skeleton/Wt.js (revision 777) > @@ -574,9 +574,12 @@ > var randomSeed = new Date().getTime(); > > var update = function(self, signalName, e, feedback) { > + if(responsesPending) > + return; > + > ${APP_CLASS}.private.autoJavaScript(); > ++responsesPending; > - > + > if (${WT_CLASS}.isIEMobile) feedback = false; > > if (quited) { > > I suppose that's not the correct one actually, but works as for me. >
We have a longstanding discussions about what Wt should be doing for these situations. There are some options: a) a simple, effective, solution would be to (always) ignore any event while the previous response has not been received yet (like you suggest). But the event is simply discarded, so the user will at least be surprised. b) to solve this, we could queue events until the previous response has been received. This in fact, does not solve the problem, because you could still have two clicks on a button that is supposed to disappear after the first click. c) we could complicate the API with a flag that allows the developer to indicate whether subsequent events should be cancelled, but, this would not be more work than: d) give responsibility to the developer to make sure a button cannot be clicked twice. He could that that by: 1) client-side: use WWidget::hide() or WWidget::disable() WPushButton *b = ... b->clicked.connect(SLOT(b, WWidget::hide)); // or perhaps nicer: b->clicked.connect(SLOT(b, WWidget::disable)); b->clicked.connect(SLOT(this, MyWidget::doStuff)); Because hide() and disable() are stateless slots, they are optimized in client-side code that runs immediately when the button is clicked. The server-side slot, doStuff() could then show() or enable() the button again if he wishes. 2) server-side: delete the widget that originated the signal (and perhaps recreate it). button_ = new WPushButton(...); button_->clicked.connect(SLOT(this, MyWidget::doStuff)); void MyWidget::doStuff() { // do stuff... delete button_; } This works because your application will process events one after the other, and, the second event will no longer be valid ("exposed in Wt talk") because the clicked Signal got deleted together with the button. All in all, I am in favor of option d). But, admittedly, this needs to be documented somewhere! And, perhaps I am wrong about the effectiveness of the two solutions? Regards, koen ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ witty-interest mailing list witty-interest@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/witty-interest