20110504

Dojo 事件( Events ) - 發佈( publish )與訂閱( subscribe )

本篇將要介紹 Dojo event 的發佈與訂閱(簡稱 pub/sub )。
所有我們在先前的文章中提到的事件,都使用已經被建立好的物件 (a DOM node, a "widget", and an effect object) 作為事件的製造者,如此我們才知道這個事件應該在哪裡發生。但是如果我們無法取得物件,或者物件尚未被建立出來該怎麼做?這就是 pub/sub framework 上場的時候了。


Pub/sub 可以註冊(在這裡稱為訂閱 subscribe )一個 "topic" 的 handler,當 topic 被發佈( publish )之後,這個事件 handler 會被呼叫。 Topic 是 Dojo 中一個特殊的名詞,代表可以有多個來源的事件的一個字串。

現在我們想要寫一個程式,其中有數個按鈕會 alert 使用者所做的某個動作,但是我們不想重複寫好幾次同樣是 alert 的回應,也不想對每個按鈕都特地做一個 wrapping object 來註冊這個重複的回應:

<button id="alertButton">Alert the user</button>
<button id="createAlert">Create another alert button</button>
 
<script>
    var alertButton = dojo.byId("alertButton"),
        createAlert = dojo.byId("createAlert");
 
    dojo.connect(alertButton, "onclick", function(evt){
        // 按下這個按鈕的時候
        // 發佈( publish )到 "alertUser" 這個 topic
        dojo.publish("alertUser", ["I am alerting you."]);
    });
    dojo.connect(createAlert, "onclick", function(evt){
        // 建立另一個按鈕
        var anotherButton = dojo.create("button", {
            innerHTML: "Another alert button"
        }, createAlert, "after");
 
        // 按下這個另外建立的按鈕
        // 發佈( publish )到 "alertUser" 這個 topic
        dojo.connect(anotherButton, "onclick", function(evt){
            dojo.publish("alertUser", ["I am also alerting you."]);
        });
    });
 
    // 以 "alertUser" 這個 topic, 
    // 註冊( Register ) 重複的 alert 事件
    dojo.subscribe("alertUser", function(text){
        alert(text);
    });
</script>

如此一來,重複的事件和事件的生產者(發生事件的物件,上例中就是按鈕)就獨立出來了。
下面是 pub/sub要注意的地方:

  • dojo.subscribe 的用法和 dojo.connect 相似(dojo.subscribe(topic, handler) or dojo.subscribe(topic, scope, handler or method name)).
  • dojo.publish 的第二個變數必須是一個陣列,陣列中的元素就是 topic 的 handler functions 的 input 變數。
  • dojo.subscribe 會傳回一個 handle ,用於 dojo.unsubscribe 以停止註冊這個 topic 的 handler (類似 dojo.connect 和 dojo.disconnect)。

沒有留言:

張貼留言