Loading ...
Sorry, an error occurred while loading the content.

Re: Subscribe to an event only once

Expand Messages
  • Nick Husher
    The method you provided really doesn t address the problem I have. I m not looking to prevent other functions in the listener stack from getting fired, I m
    Message 1 of 4 , Jul 6, 2007
    • 0 Attachment

      The method you provided really doesn't address the problem I have. I'm not looking to prevent other functions in the listener stack from getting fired, I'm trying to prevent a listener from getting fired on the second occurance of an event. The behavior I'm looking for is best decribed by explaining how I used it after I had written it;

      I have a page with two animating elements, one is a login box that expands when clicked to reveal the user name and password fields. The other is a modal dialogue box that fades in over the rest of the page. I wanted to have the account panel box collapse automatically if it's open before the modal dialogue box begins to animate in.

      I tried attaching a listener on-the-fly to the account panel's AnimOut.onComplete that will call the reveal function on the modal box after the account panel is finished, but I found that I needed to be careful about unattaching that listener before I continued. Else, whenever the account panel was closed, for any reason at all, it would trigger the modal dialoge.

      I'm a big fan of clean, obvious, uncomplicated code in Javascript, particularly for simple event handlers, I realized that this would be a real pain in my programming style. Instead of writing,

      AnimOut.onComplete.subscribe(ModalDialogue.show);

      I'd have to write

      function f() {
      ModalDialogue.show();
      AnimOut.onComplete.unsubscribe(f);
      }

      AnimOut.onComplete.subscribe(f);

      Alternatives to the above syntax didn't work for me, those methods are:

      /*
      This is unclear; it's possible that ModalDialogue.show will be unsubscribed before it ever actually executes, depending on how the event handler stack is implemented. Rather than muck about in the YUI source, I'd rather treat this as a black box. Additionally, the event handler stack will always have one (or more) extra anonymous functions that will get called whenever the event fires, because they cannot be unsubscribed from the event stack. This is a bad thing for long-lived RIA pages, because it's essentially a very minor memory leak.
      */
      AnimOut.onComplete.subscribe(ModalDialogue.show);
      AnimOut.onComplete.subscribe(function() { AnimOut.onComplete.unsubscribe(ModalDialogue.show); });

      /*
      This is also unclear.  It also has the same memory leak problem as above, except for ModalDialoge.showAnim. Certainly, I could attach the second event listener somewhere at the top and do it once, but then we start getting into spaghetti code land.
      */
      AnimOut.onComplete.subscribe(ModalDialogue.show);
      ModalDialogue.showAnim.onComplete.subscribe(function() {
      AnimOut.onComplete.unsubscribe(ModalDialogue.show);
      });

      Rather than mess about with complex solutions, I'd rather just call one function and have it 'just work'. With the code I provided, I can do exactly what I'm looking for with one line:

      AccountPanel.AnimOut.onComplete.subscribeOnce(ModalDialogue.show);

      It attaches the event handler, and then after it fires, it unattaches itself cleanly.
    Your message has been successfully submitted and would be delivered to recipients shortly.