Wednesday, March 21, 2012

Useful Event Handlers for Modal Dialogs

‹prev | My Chain | next›

Tonight I revisit the Dart from a few nights back. There are a couple of minor things that don't quite work or I would like to add.

First up, I would like to remove the modal dialog if I press the escape key. This is simple enough:
window.
      on.
      keyDown.
      add((event) {
        if (event.keyCode == 27) remove();
      });
I add that to an _attachHandlers() private method and invoke that when the dialog is first shown. Easy peasy.

Next a bug. When I look at the page with the Dart console open (which is nearly all the time), it looks somewhat OK:


But when I remove the Dart console, I find:


Ugh.

There has to be a built-in event handler that will fire when the viewport size changes like that, right? For my first try, I put tracer bullets into window.on.resize and, amazingly that seems to hit the target. So I add another handler to _attachHandlers():
  _attachHanders() {
    // handle ESC here...

    window.
      on.
      resize.
      add((event) {
        _drawBackground();
      });
  }
This is only half the solution however. It will no do to leave this handler in place after the modal dialog is closed. After close, the handler needs to be removed. In Dart, I have to use an explicitly named function in order to be able to remove it. I could make a wrapper around _drawBackground(), but that seems superfluous. I cannot add _drawBackground() directly to add() because all event listeners are required to accept a single parameter (then event).

Oooh.... but wait. I can define _drawBackground() such that it takes an optional parameter. I will never care about that optional parameter so, by convention, I use the _ parameter:
  _drawBackground([_]) {
    //  do normal draw stuff here...
  }

  _attachHanders() {
    // Handle ESC here ...

    window.
      on.
      resize.
      add(_drawBackground);
  }
With that, I can add a corresponding _removeHandlers() to the remove() method, which removed the named _drawBackground() "listener":
  Node hide() {
    _removeHandlers();
    bg.remove();
    return el.remove();
  }

  _removeHandlers() {
    window.
      on.
      resize.
      remove(_drawBackground);
  }
Nice. Either this is fairly intuitive or I am getting the hang of Dart. Either way, implementing these handlers was quite easy.


Day #332

2 comments:

  1. In fact the _removeHandlers() code doesn't do what you think it does:
    http://code.google.com/p/dart/issues/detail?id=144&q=closure&colspec=ID%20Type%20Status%20Priority%20Area%20Owner%20Summary

    ReplyDelete
    Replies
    1. Yup. You are correct: http://japhr.blogspot.com/2012/03/really-really-removing-event-handlers.html. Thanks for pointing that out :)

      Delete