Created
January 25, 2017 22:41
-
-
Save vreality64/f7aad668c2ed137e80eebe640d501eed to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var instance = new Hello(); | |
instance.on("test", { | |
somethig: function () { | |
this.fireEvent("next", this.name); | |
}, | |
name: "world" | |
}); | |
// fireEvent 는 instance 의 함수다. | |
// 그런데 object 의 메서드 내에서 this 참조를 할 때 instance 가 되게 하고 싶다. | |
// 왜냐하면 해당 메서드와 instance 와의 결합을 하고 싶지 않기 때문이다. 모듈을 만들기 위해선 불필요한 커플링을 없애야한다. | |
// | |
// 방법 1: | |
// object 에 함수를 할당할때 .bind(instance)호출 | |
// > 여전히 커플링 발생. 또 함수가 여러개면 각각 bind를 해줘야하는 중복 발생 | |
// | |
// 방법 2: | |
// 직접 bindObj 를 명시하는 방법 | |
// 또는 referenceObj 를 명시하는 방법 | |
// | |
instance.on("test", { | |
something: function () { | |
this.fireEvent("next", this.name); | |
}, | |
name: "world", | |
binding: instance | |
}); | |
on: function (type, options) { | |
if (!this[type]) { | |
this.attach(type, options); | |
} | |
// case flicking, map, pagination | |
this._bindEach(options); | |
} | |
_bindEach: function (options) { | |
// 근데 이렇게 this를 바꾸면 문제가 있겠지 | |
this.eachType.attach.call( | |
options.binding || this, options | |
); | |
} | |
// 이걸 하는 목적이 | |
// 이벤트 연동만 해주는 컨트롤러를 만들고 싶은거. A모듈 이벤트가 B, C 모듈 이벤트를 발생시키고, 그와 반대의 경우도 있고. 여러 경우에 대해 view 바인딩을 해주려는 것. | |
// | |
// 그러면 필요한게 모듈별 이벤트 on, fire API. 각 API 를 통해 변경된 모듈 | |
// 을 알고, 해당 모듈이 업데이트 되었을 때 변경사항을 반영할 수 있다. | |
// | |
// Q. 각 모듈들이 custom event listening 을 지원한다면, 지금 형태로 갈 필요가 없는것 아닌가?? 각 모듈에 custom event 를 직접 attach 해서 처리콜백은 외부에서 제공해준다면, 내가 원하는 그림이 바로 나오는데?? | |
// | |
// 그렇다면 코드가 이렇게 나가겠지. | |
instance.on("custom", function () { | |
외부 커스텀 이벤트. | |
내부 모듈에 해당 이벤트를 broadcast 한다. | |
}); | |
instance.on("custom", "flicking", function () { | |
// 여기서 this는 전역이 아니라 | |
// instance 모듈 | |
var data = { moved: 이동한 idx }; | |
this.fireEvent("custom", "map", data); | |
this.fireEvent("custom", "pagination", data); | |
}); | |
myModule.fireEvent: function (name, context, data) { | |
if (!data) { | |
data = context; | |
context = undefined; | |
} | |
// this는 내가 만든 모듈 | |
// fireEvent 는 실제 모듈에서 실행 | |
this.module[context].fireEvent(name, data); | |
} | |
// module | |
$Class({ | |
$init: function (config) { | |
this._initComponent(config); | |
}, | |
_initComponent: function (config) { | |
for (var name in config) { | |
if (config.hasOwnProperty(name)) { | |
this.module[name] = new config[name].constructor; | |
} | |
} | |
}, | |
on: function (name, context, callback) { | |
if (!callback) { | |
callback = context; | |
context = undefined; | |
} | |
this.module[context].attach.call(this, callback); | |
}, | |
// context or delegation 이라는 이름이 적당 | |
fireEvent: function (name, context, data) { | |
if (!data) { | |
data = context; | |
context = undefined; | |
} | |
// visited 를 이용해서 circular 를 방지하고자 함. | |
// TODO: visited 초기화는 어디서 하지? | |
data.visited = data.visited || []; | |
if (data.visited.indexOf(name) >= 0) { | |
return; | |
} | |
data.visited.push(name); | |
// this는 내가 만든 모듈, fireEvent 는 실제 모듈에서 실행 | |
this.module[context].fireEvent.call(this, name, data); | |
} | |
}); | |
// usage | |
var flickingOpt = { | |
// constructor: controller.of.flicking, | |
options: { | |
// 실제 이벤트 처리 핸들러는 여기에 있다. | |
flicking: function (event) { | |
var data: { visited: ['flicking'], moved: event.nContentsIndex }; | |
this.fireEvent('update.view', 'flicking', data); | |
}.bind(instance) | |
} | |
}; | |
// map, pagination 모두 동일함 | |
var instance = new my.module ({ | |
flicking: flickingOpt, | |
// map, pagination module... | |
}); | |
instance.on('update.view', function (data, context) { | |
// 커스텀 이벤트는 | |
// 내부 모듈에 해당 이벤트를 broadcast 한다. | |
for (var name in this.module) { | |
if (this.module.hasOwnProperty(name)) { | |
this.module[name].fireEvent.call(this, data, context); | |
} | |
} | |
}); | |
nstance.on('update.view', 'map', function (eventName, data) { | |
this.fireEvent(eventName, 'flicking', data); | |
this.fireEvent(eventName, 'pagination', data); | |
}); | |
instance.on('update.view', 'flicking', function (eventName, data) { | |
this.fireEvent(eventName, 'map', data); | |
this.fireEvent(eventName, 'pagination', data); | |
}); | |
instance.on('update.view', 'pagination', function (eventName, data) { | |
this.fireEvent(eventName, 'map', data); | |
this.fireEvent(eventName, 'flicking', data); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
data.visited = data.visited || [];
if (data.visited.indexOf(name) >= 0) {
return;
}
data.visited.push(name);
visited 를 객체로 바꾸자
data.visited || {};
if (data.visited[name]) {
return;
}
data.visited[name] = true;