views:

223

answers:

3

I have an adobe flex datagrid with a simple custom label itemrenderer in one of the columns. Clicking on the itemrenderer fires off a cairngorm event, which results in a service call being made, and the data from the service call populates a TitleWindow.

Even though I have set the doubleClickedEnabled property to false, its still possible to sometimes double click the item renderer, resulting in two service calls being made, and two TitleWindows being shown. In other cases, triple clicking seems to trigger the undesired result as well.

Is there any method to prevent this kind of behaviour?

+2  A: 

Keep track of when you get a click event and if you get two within a certain amount of time (250ms) ignore the second.

var lastTime:Date = new Date(0);

function OnClickHandler(event:Event):void {
    if ((new Date()).time - lastTime.time < 250) {
        return;
    }
    lastTime = new Date();
    ...
}
Sam
I really like this method, because I can extend it to all service calls.I have created a bindable ServiceModel singleton, that stores the lastTime, method and service every time a service call is made.I then modified the baseDelegate to check the ServiceModel parameters (lastTime, method, service) against the current service call - if its the same method and service name, and the time is less than 500ms, then dont process it.Do you forsee any issues with this?
JonoB
@JonoB, this could be a problem if there is a legitimate reason to call the same service method in a loop. Contrast this to the user having a legitimate reason to click a link multiple times within 250ms, and it seems like doing this on the event handler would be better.
Sam
There are no occurances in my app of having the same service call made from the same client within 250 or 500ms. If there is, then its probably an error! There are certainly no service calls in a loop. I also have these single click links in a lot of places in my app, and wouldnt really want to go and create an event handler for each of them.
JonoB
A: 
// class variable section
var lastTime:Date = null;

...

function handler(evt:Event):void{
    var currentTime = new Date();
    if (lastTime === null){
         lastTime = currentTime;
    } else {
         var diff = currentTime.milliseconds() - lastTime.milliseconds();
         if (diff <= 250) // try some other intervals to get best result for you.
             return;
         else 
             lastTime = currentTime;
    }
    ... the rest of your code.
}
coolnalu
Nope. **First**, this is a lot of code for a simple task. Simplify. **Second**, `milliseconds` will return the current millisecond component, not the total milliseconds, and will not achieve the required result. **Third**, `milliseconds` is a property, not a method, so no parenthesis.
Sam
A: 

The best way to do this is to set a flag in your itemRenderer to note that it has been clicked once. This prevents it from sending another cairngorm event until the result of the first one is returned, at which time you reset the flag, enabling it to be clicked again.

For brevity, the following code assumes everything is happening within the same scope. If it isn't you'll have to send and receive events to and from the itemRender from some other context.

[Bindable]
var _clickEnabled:Boolean = true;

private function doClickStuff() : void {
  if (_clickEnabled) {
    // fire your event
    _clickEnabled = false;
  } 
}

private function onEventReturnHandler(event:Event) : void {
  // do whatever it is you're going to do
  _clickEnabled = true;
}
Robusto