====== 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~~