EventEmitter (EventDispacher) の階層構造
フロントエンドにおいて、それなりに普遍的な問題な気もするんだけど、
例えば、何かDOMと紐づくクラスを作ると、
どうしても親子関係を持たせたくなって
class ParentUnit extends EventEmitter constructor: -> @childUnit = new ChildUnit render: -> """<div>#{@childUnit.render()}</div>""" class ChildUnit extends EventEmitter constructor: -> someHandler: (e) -> @emit "childevent", e render: -> "<p>child unit</p>" parentUnit = new ParentUnit parentUnit.on "childevent", -> # こうしたい
このとき、子から親にどうやってイベント(クリックとか)を伝えるかという問題に直面する。
1. バブリングさせる
class ParentUnit constructor: -> @childUnit = new ChildUnit @childUnit.on "childevent", @handlerChildEvent handlerChildEvent: (e) => @emit "childevent", e
メリット
- わかりやすい
- 子が疎結合を維持できる
- イベントを消したりまとめたり変形できる
デメリット
- 階層が深くなるとめんどい
- イベントを消したりまとめたり変形される
2. グローバルなEventEmitterを使う
globalEventEmitter = new EventEmitter class ChildUnit someHandler: (e) -> globalEventEmitter.emit "childevent", e
メリット
- 楽
デメリット
- 良くない
3. 親を引き連れ回す
class ChildUnit constructor: (@parent) -> someHandler: (e) -> @parent.emit "childevent", e
メリット
- イベントがそのまま届く
デメリット
- 気をつけないと子が密結合っぽくなる
- 似たようなことをするのに表現の仕方が多すぎる
4. EventEmitterをメンバとして持つ
parentEvent = new EventEmitter class ParentUnit constructor: (@eventEmitter) -> @childUnit = new ChildUnit @eventEmitter class ChildUnit constructor: (@eventEmitter) -> someHandler: (e) -> @eventEmitter.emit "childevent", e parentUnit = new ParentUnit parentEvent parentEvent.on "childevent", ->
メリット
- イベント用のオブジェクトが独立できる
デメリット
- あまり見ない
- イベント用のオブジェクトが独立してる
5. そもそも親子関係を持たせない
メリット
- 親も疎結合になる
- 複雑な親子関係を組む時、見通しが良い
デメリット
- めんどい
ちなみに eventemitter2 は名前空間を切れる