Views 와 Widgets사이에 커플링을 막고자 사용함.
뷰의 상하의 간에 메시지를 주고 받고 해야 한다.
일반적인 옵저버 패턴.


Broadcasting and Listening

eventHandlerA.on('A', function(data){ alert(data.msg); });  // alerts 'ALERT!' 

eventHandlerA.emit('A', message);//trigger

emit나 trigger나 같지만, emit는 밖에서 호출할 때, trigger는 안에서 호출할 때.


Piping
이벤트를 아래로 흐르게 해준다.(like 캡처링)

eventHandlerA.pipe(eventHandlerB).pipe(eventHandlerC);
eventHandlerC.on('A', function(data){alert(data.msg)});  // alerts 'ALERT!'
eventHandlerA.emit('A', message);


Subscribing

이벤트를 위로 올려준다.(like 버블링)

eventHandlerC.subscribe(eventHandlerB);
eventHandlerB.subscribe(eventHandlerA);
eventHandlerC.on('A', function(data){alert(data.msg)});  // alerts 'ALERT!'
eventHandlerA.emit('A', message);


Filtering

이벤트를 중간에 필터링 해줌.

var myFilter = new EventFilter(function(type, data) {
    return data && (data.msg === 'ALERT!'); //true or false
});

eventHandlerA.pipe(myFilter).pipe(eventHandlerB);
eventHandlerB.on('A', function(data){
    alert('piped message: ' + data.msg);
});



Mapping 

라우팅하듯이 특정 eventHandler에 이벤트를 전달한다.(개인적으론 불필요하다고 생각)

var myMapper = new EventMapper(function(type, data) { return (data && (data.direction === 'x')) ? eventHandlerB : eventHandlerC; });

eventHandlerA.pipe(myMapper); eventHandlerB.on('A', function(data){ alert('B direction : ' + data.direction); }); eventHandlerC.on('A', function(data){ alert('C direction : ' + data.direction); }); eventHandlerA.trigger('A', {direction : 'x'}); // pipes to eventHandlerB eventHandlerA.trigger('A', {direction : 'y'}); // pipes to eventHandlerC

pipe만 가능하다.(당연한다 subscribe가 되려면 mapping에서 이벤트를 받아야 함)


Arbitration

Mapping하고 비슷한 느낌인데 mode별로 이벤트를 등록할 수 있다.
한번에 하나의 모드만 가능하고 setMode로 하면 해당 모드만 동작.
이것도 왜 있어야 하는지 모르겠다.


var eventArbiter = new EventArbiter();

eventArbiter.forMode('routeA').on('A', function(data){
    alert('subscribed message: ' + data.msg);
});
eventArbiter.forMode('routeB').on('B', function(data){
    alert('subscribed message: ' + data.msg);
});

eventArbiter.setMode('routeA');

eventArbiter.forMode('routeA').emit('A', message); // alerts 'ALERT!'
eventArbiter.forMode('routeB').emit('B', message); // does nothing. Mode is not set.

eventArbiter.setMode('routeB');

eventArbiter.forMode('routeA').emit('A', message); // does nothing. Mode is not set.
eventArbiter.forMode('routeB').emit('B', message); // alerts 'ALERT!'


Event Handling Inside a Widget

자체적으로 몇가지 룰이 있다.

External to a Widget:

widget.trigger : the interface to talk to a widget

widget.on : the interface to listen to a widget

widget.pipe : the interface to pipe from a widget

widget.subscribe : the interface to subscribe from a widget


Internal to a Widget:

receive events via widget.eventInput

broadcast events via widget.eventOutput

widget.emit는 없음.


//아래와 같이 인풋 핸들러를 등록.

EventHandler.setInputHandler(widget, eventHandlerA);
eventHandlerA.on('B', function(data){alert(data.msg)});
widget.trigger('B', message);


Listening

setInputHandler으로 등록한 놈이 받음

// Child widget
function Child(){
    // setup input and output handlers
    this.eventOutput = new EventHandler();
    this.eventInput = new EventHandler();
    EventHandler.setInputHandler(this, this.eventInput);
    EventHandler.setOutputHandler(this, this.eventOutput);

    this.eventInput.on('hires tutor', function(){
        alert('Accepted to Harvard');
    }.bind(this));
}



// Parent widget
function Parent(){
    // setup input and output handlers
    this.eventOutput = new EventHandler();
    this.eventInput = new EventHandler();
    EventHandler.setInputHandler(this, this.eventInput);
    EventHandler.setOutputHandler(this, this.eventOutput);

    this.child = new Child();
    this.eventInput.on('bad report card', function(){
        this.child.trigger('hires tutor');
    }.bind(this));
}

var parent = new Parent();
parent.trigger('bad report card');


Broadcasting

setOutputHandler으로 등록한 얘가 전달.

EventHandler.setInputHandler(widget, eventHandlerA);
eventHandlerA.on('B', function(data){alert(data.msg)});
widget.trigger('B', message);



보면서 느낀건 전체적으로 과한 느낌이 있다.

너무 많다. 이런 경우 나중에 이벤트로만 넣으면 데이터가 흘러갈 때 문제가 있을 것 같다.
특히 mapping은 불필요. 데이터가 deep copy되지 않기 때문에 중간에 값을 바꾸면 디버깅의 거의 불가능하고 경험상 이벤트 종류는 너무 할 정도로 간단하게 가야 한다. 복잡하게 되면 나중에 엄청 고생함.

Posted by 전용우
,