2011-11-11 10 views
13

저는 모듈 패턴을 구현 중이며 이벤트 리스너/핸들러를 정의하고 등록하는 최선의 방법을 알고 싶습니다. 작품에 따라,하지만 어쩌면 더 나은/간단한 방법이 ...자바 스크립트 모듈 패턴 이벤트 및 리스너

var MODULE = function() { 

    // private 
    var _field1; 
    var _field2; 

    function localFunc(p) { 
     alert('localFunc'); 
    } 

    // public 
    return { 
     // properties 
     prop1: _field1, 

     // events 
     myEvent1Handler: {}, 
     myEvent1: function() {myEvent1Handler();}, 
     myEvent2Handler: {}, 
     myEvent2: function() {myEvent2Handler();}, 

     addListener: function (event,func) { 
      if (event == "myEvent1") 
       myEvent1Handler = func; 

      if (event == "myEvent2") 
       myEvent2Handler = func;  
     }, 

     // public methods 
     method1: function (p) { 
      alert('method1 says:' + p); 
      MODULE.myEvent1(); 
     }, 
     method2: function (p) { 
      alert('method2 doing stuff'); 
      localFunc(p); 
      MODULE.myEvent2(); 
     } 

    }; 
}(); 

// register for events 
MODULE.addListener("myEvent1",function(){alert('fired1');}); 
MODULE.addListener("myEvent2",function(){alert('fired2');}); 

// use module (only event1 should fire!) 
MODULE.method1("hello"); 

그것을 밖으로 시도 :

http://jsfiddle.net/RqusH/3/

는 myEventx, myEventHandlerx과의 addListener을 가지고 많은 일처럼 보인다 ?

+1

'addListener()'를 호출하면 전달 된'func' 매개 변수를 참조하는 _global_ 변수로'myEvent1Handler' 또는'myEvent2Handler'가 생성되지 않습니까? 'myEvent1' 함수에서'this.myEvent1Handler = ...'- 그리고'this.myEvent1Handler()'를 제외하고는 이미 객체에 정의 된 동일한 이름의 속성을 설정하지 않을 것입니다. (또는'MODULE.myEvent1Handler'는'method1'에'MODULE.myEvent1()'이있는 것과 같습니다.) – nnnnnn

+0

실제로 어떤 문제를 해결하려고합니까? 이것은 실제로 아무것도하지 않고 비계를 만드는 많은 오버 헤드처럼 보입니다. 아마도 우리가 실제로 성취하려는 것을 알고 있다면, 우리는 당신이 그것을하기위한 최선의 방법을 찾도록 도울 수 있습니다. – jfriend00

+0

감사합니다 ... 나는 MODULE의 사용자가 이벤트에 연결할 수 있도록 MODULE에서 이벤트를 원합니다. MODULE 메서드는 비동기 요청 (jquery 사용)을 가지므로 이벤트를 사용하여 비동기 요청이 완료되었을 때 나타냅니다. – ZimSystem

답변

9

일반적으로 특정 구현 (특히 jQuery와 같은 제 3 자 라이브러리에 종속 된 아키텍처)에 대한 아키텍처 질문에는 응답하지 않지만 내 구현은 재사용 가능성을 촉진하므로 여기에 패턴을 이야기합니다. 작은 jQuery 플러그인 인 $ .eventable은 jQuery의 이벤트 메소드로 JavaScript 객체를 보완한다.

이 플러그인을 사용하면 간단한 호출로 모든 객체 (또는 클래스 인스턴스)에서 이벤트 처리 기능을 구현할 수 있습니다.

jQuery.eventable = function (obj) { 
    // Allow use of Function.prototype for shorthanding the augmentation of classes 
    obj = jQuery.isFunction(obj) ? obj.prototype : obj; 
    // Augment the object (or prototype) with eventable methods 
    return $.extend(obj, jQuery.eventable.prototype); 
}; 

jQuery.eventable.prototype = { 

    // The trigger event must be augmented separately because it requires a 
    // new Event to prevent unexpected triggering of a method (and possibly 
    // infinite recursion) when the event type matches the method name 
    trigger: function (type, data) { 
    var event = new jQuery.Event(type); 
    event.preventDefault();     
    jQuery.event.trigger(event, data, this); 
    return this; 
    } 
}; 

// Augment the object with jQuery's event methods 
jQuery.each(['bind', 'one', 'unbind', 'on', 'off'], function (i, method) { 
    jQuery.eventable.prototype[method] = function (type, data, fn) { 
    jQuery(this)[method](type, data, fn); 
    return this; 
    }; 
}); 

그 조각을 포함 할 경우,이 같은 솔루션을 구현할 수 있습니다

var MODULE = function() { 

    // private 
    var _field1; 
    var _field2; 

    function localFunc(p) { 
    alert('localFunc'); 
    } 

    // public 
    return $.eventable({ 

    // properties 
    prop1: _field1, 

    // public methods 
    method1: function(p) { 
     alert('method1 says:' + p); 
     this.trigger('myEvent1'); 
    }, 

    method2: function(p) { 
     alert('method2 doing stuff'); 
     localFunc(p); 
     this.trigger('myEvent2'); 
    } 

    }); 
}(); 

// register for events 
MODULE.on("myEvent1", function() { 
    alert('fired1'); 
}); 
MODULE.on("myEvent2", function() { 
    alert('fired2'); 
}); 

// use module (only event1 should fire!) 
MODULE.method1("hello"); 
모듈 이제 다음 호출 방법있다

:

MODULE.on(event, /* data, */ handler); 
MODULE.bind(event, /* data, */ handler); 
MODULE.one(event, /* data ,*/ handler); 
MODULE.off(event, handler); 
MODULE.unbind(event, handler); 
MODULE.trigger(event /*, data */); 

이벤트는 공간 -이다 어디 구분 된 이벤트 목록, 처리기는 콜백이며 데이터는 콜백에 전달할 선택적 값입니다.

자세한 내용은 jQuery's documentation을 참조하십시오.

+0

이것은 탁월하며 완벽하게 사용하는 패턴과 일치합니다. 감사! 이 일을 아주 조심스럽게 진행할 것입니다 ... – Ricky

2

공개 모듈 패턴은 익명 개체를 반환합니다. 대신이를 변수로 선언하고 리턴하면 이벤트를 발생시키기위한 모듈 내부와 외부에서 이벤트에 응답하기 위해 표준 jQuery 이벤트 메소드를 아주 쉽게 사용할 수 있음을 의미합니다. 미리 jQuery 객체로 변환해야한다.

var controller = (function() 
{ 
    function doAThing() 
    { 
    // Things getting done here 
    $(interface).trigger("complete"); 
    } 

    var interface = { 
    doAThing: doAThing 
    }; 
    return interface; 
})(); 

$(controller).on("complete", function() { console.log("Thing Done"); }); 
controller.doAThing(); 
관련 문제