niedziela, 21 sierpnia 2011

Własny EventListener

Kolejny raz w mojej pracy zaszła potrzeba zaimplementowania EventListener`a. Kiedy widzę, że muszę napisać drugi raz ten sam kod zawsze refaktoryzuję ten istniejący tak aby wspólną jego część przenieść do jednego niezależnego miejsca w kodzie.
Ewentualne zmiany kodu w więcej niż jednym miejscu nie wróżą niczego dobrego. Pozwólmy aby nasza dalsza praca nad kodem była miła i przyjemna. JavaScript doskonale nam w tym pomoże.

var EventListener = function(enames){
  var events = {};
  for( var i = 0; i < enames.length; ++i ){
    events[enames[i]] = [];
  }
  return {
    add: function(ename, fn){
      var that = this;
      var i = events[ename].push(fn) - 1;
      return {
        detach: function(){
          delete events[ename][i];
          return {
            attach: function(){
              return that.add(ename, fn);
            }
          };
        }
      };
    },
    remove: function(ename, fn){
      var that = this;
      delete events[ename][
        events[ename].indexOf(fn)
      ];
      return {
        attach: function(){
          return that.add(ename, fn);
        }
      };
    },
    invoke: function(ename){
      var arg = [].slice.call(arguments, 1);
      var res = [];
      for( var i in events[ename] ){
        if( events[ename].hasOwnProperty(i) ){
          res.push(events[ename][i].apply(this, arg));
        }
      }
      return res;
    },
    toString: function(){
      return '[EventListener: '+ enames.join(', ') +']';
    }
  };
};

Klasa EventListener pozwala nam na utworzenie własnego nasłuchiwacza zdarzeń. Dzięki niej w wystarczy, że w jednym miejscu aplikacji stworzymy kod odpowiedzialny za wykrycie jakiegoś zdarzenia, a w wielu innych dowolnych miejscach tylko podłączamy się do niego. Innych zalet powyższego wzorca projektowego chyba nie muszę tłumaczyć.
Obiekt zwracany przez metodę add posiada metodę detach, która pozwala odpiąć dodane zdarzenie. Ta z kolei zwraca obiekt zawietający metodę attach, która pozwala na powrotne podpięcie zdarzenia itd.
Podobnie jest z metodą remove naszej klasy. Z tą różnicą, że ta w pierwszej kolejności zwraca obiekt z metodą attach.
Metoda invoke oczywiście służy do wywołania funkcji podpiętych pod zadane zdarzenie. Pierwszym argumentem tej metody jest nazwa wywołanego zdarzenia. Kolejne argumenty są dowolne i opcjonalne. Będą one przekazane do każdej z podpiętych do zdarzenia funkcji.

Brak komentarzy:

Prześlij komentarz