====== Monitor idle state with custom events ======
최근 ajax 관련 project를 하면서, 유저가 동작을 멈췄는지 계속 조작하고 있는지 모니터링할 필요성이
제기되었다. 이런저런 궁리를 해도 생각되로 되지 않던 차에 Google 검색에서 그럴 듯한 것을 발견하였다.
**Kaushal Sheth**씨의 [[http://thinkweb2.com/projects/prototype/detect-idle-state-with-custom-events/|2007/10/17]]일자로 투고된 기사에 유용한 소스가 있었다. 하지만 문제는 project에서
사용하고 있던 **dojo toolkit**이 아니라 **prototype** 프레임워크로 작성되어 있었다.
**dojo toolkit**으로 검색해 봐도 그럴듯한 것이 없어서 결국 위의 블로그 기사를 토대로 **dojo toolkit**으로 포팅하기로
마음먹게 되었다. 자세한 것은 원문을 확인하기 바라고, **prototype**과 **dojo toolkit**의 다른점만 짚고 넘어가고자 한다.
{{keywords>Monitor Detect idle state custom event dojo toolkit}}
===== Declaring Class =====
제일 먼저 눈에 띄는 차이점이 Class의 선언방법이다.
prototype에서는 다음과 같은 선언방식을 사용한다.
var Employee = Class.create(); /* 주의: 클래스도 객체다! 고로 var! */
Employee.prototype = {
initialize : function(name, dept) { /* 주의: 생성자의 이름은 "initialize" 이다. ':' 이다! */
this.name = name || "";
this.dept = dept || "general";
}, /* 주의: 여기 쉼표!! */
toString : function() { /* 주의: ':' 이다! */
return "name=" + this.name + ",dept=" + this.dept;
} /* 주의: 여기에는 쉼표가 없다!! */
});
반면에 dojo toolkit에서는 다음과 같이 선언한다.
dojo.declare("Employee", null, { /* 주의: 클래스 이름을 따옴표로 둘러싼다! */
constructor : function(name, dept) { /* 주의: 생성자 이름은 "constructor" 이다! */
this.name = name || '';
this.dept = dept || 'general';
},
toString : function() {
return "name=" + this.name + ",dept=" + this.dept;
}
});
===== Array utility =====
다음으로 Array의 elements에 접근하는 방법이 서로 다르다. **prototype**의 경우 다음과 같은 접근방법을 사용한다.
['one', 'two', 'three'].each(function(s) {
alert(s);
});
**dojo toolkit**의 경우에는 다음과 같다. Array가 인수로 들어가는 것을 빼면 큰 차이는 없다.
dojo.each(['one', 'two', 'three'], function(e){
alert(e);
});
===== Add Event Listener =====
다음으로 event listener의 등록방법에서 차이를 보인다. 먼저 **prototype**의 경우를 살펴보자.
예를 들어 다음과 같이 간단한 form 이 있다고 가정하자.
여기에 form을 submit할때 checkForm이라는 메소드를 등록하고 싶다. 물론 form태그에 집어넣어도 되겠지만, 좀 더 깔끔하게 처리
하고 싶다. 그럴경우에 다음과 같이 page를 로딩할 때 form object에 이벤트를 등록하는 방법이 있다.
Event.observe(window, 'load', function() {
Event.observe('signinForm', 'submit', checkForm);
});
훨씬 깔끔해 보이지 않는가?8-o
이 코드를 **dojo toolkit**으로 다음과 같이 표현할 수 있다.
dojo.addOnLoad(function(){
dojo.connect(dojo.byId('signinForm'), 'submit', 'checkForm');
});
===== Trigger Custom Event =====
마지막으로 Custom Event를 발생시키는데서 **prototype**과 **dojo toolkit**이 큰 차이를 보인다.
**prototype**에는 **%%fire(eventName[, memo]) -> Event%%**를 이용해 custom event를 쉽게 생성할 수 있다.
예를 들면 다음과 같다.
document.observe("widget:frobbed", function(event) {
console.log("Element with ID (" + event.target.id +
") frobbed widget #" + event.memo.widgetNumber + ".");
});
var someNode = $('foo');
someNode.fire("widget:frobbed", { widgetNumber: 19 });
//-> "Element with ID (foo) frobbed widget #19."
여기서 memo는 나중에 event를 통해서 접근할 수 있어서, 어떤 값을 저장하는데 상당히 편리하다.
이에 비해 **dojo toolkit**은 [[http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/event-system/publish-and-subscribe-events|Publish/Subscribe]]라는 강력한 %%Event System%%을 가지고
있다. **prototype**의 fire에 해당하는 것이 %%dojo.publish%%이고, event를 listener에 연결하는
것이 %%dojo.subscribe%%이다.
어떤 의미에서는 [[study:java:design_pattern:observer|Observer Pattern]]이라고 볼 수 있다. publish하는
쪽에서는 누가 subscribe를 해도 신경쓸 필요가 없다. \\ 덕분에 event와 listener사이의 decoupling(분리)
가 가능하게 되었다. 그만큼 유연하고 강력한 event system이라고 생각한다.
사용예는 다음과 같다.
dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
dojo.publish("alerts", [ "read this", "hello world" ]);
//
===== Demo page =====
Here’s a little [[http://ria-web.info/test/monitor_demo.html|demo page]] to see this in action.
===== reference =====
- [[http://thinkweb2.com/projects/prototype/detect-idle-state-with-custom-events/|Detect idle state with custom events]]
- [[http://iolothebard.tistory.com/309|Create javascript class]]
~~DISCUSSION~~