原文链接:http://www.cnblogs.com/didi/archive/2010/06/13/1757894.html

//dojo.publish 和 dojo.subscribe  :dojo实现的简便强大的观察者模式

发布/预订通信

虽然dojo.connect提供的直接”连接式“通信能够解决不少问题,但在需要多个部件匿名通信情况下,则更适合使用间接的”广播式“通信。

在这些情况下,可以使用dojo.publish 和 dojo.subscribe 。 
一个经典的例子就是按照一对多的关系实现一个JavaScript对象与其他对象之间的通信。此时,与建立并管理多个具有高内聚性的dojo.connect连接相比,更简单方案应该是让一个部件在事件发生时发布通知(同事也可以传递数据),而让其他部件能够预订该通知并在事件发生时自动执行相应操作。这种方式的好处在于负责广播的对象不需要知道什么对象预订了通知,甚至无需知道其他对象是否存在,【设计模式中典型的观察者模式】

发布/预订通信的API。(调用dojo.subscribe方法时可以省略context参数。该方法在内部能够按照我们的意愿处理参数“与dojo.connect方法一样”)


dojo.publish API

//事件发布 dojo.publish(/*String*/ topic , /*Array*/ args )  //topic发布的事件主题,args发布的事件参数  //事件订阅 dojo.subscribe(/*String*/ topic ,                 /*Object | null*/ context ,                 /*String | Function*/ method )//返回一个句柄对象 //topic要订阅的事件主题,  //退订,取消订阅 dojo.unsubscribe(/*Handle*/ handle) //handle 就是要退订的事件的句柄  //【说明:和dojo.connect对象返回的句柄对象一样,dojo.subscribe返回的句柄对象也可以看成是一个黑盒子,仅在退订的时候才有用】

下面是一个使用dojo.publish和dojo.subscribe的示例:


dojo.publish and dojo.subscribe

 function Tom(topic) {     this.topic = topic;     this.hello = function () {         alert("Hello,I'm Tom!");
//Tom直接发布信息,不针对某个具体的目标 dojo.publish(this.topic); } }
function Jerry(topic) { this.topic = topic; this.hello = function () { alert("Hello,I'm Jerry"); }
//Jerry直接预订信息,但不针对某个具体的来源 dojo.subscribe(this.topic, this, "hello"); }
var tom = new Tom("/hello"); var jerry = new Jerry("/hello");
tom.hello();

第一个方法tom先是publish 发布了主题,第二个方法Jerry又subscribe订阅了方法. 【大家应该注意到倒数第2,第3行,事件主题是个字符串,并且字符串的开头是一个正斜杠。这是dojo的推荐写法,约定在主题名称前添加一个正斜杠,由于在JavaScript中,代码中正斜杠不常用,因此可以很容易的识别主题名称】

dojo.connect只能在特定的来源于特定的目标之间建立连接,而发布/订阅通信由于采用广播方式,因此对发送通知(或者是发布主题的事件)的来源和接收通知(或者注册订阅事件)的目标没有任何限制。松散耦合的架构之所以强大,原因就在于他能以最低的投入和最简单的设计,使应用程序可以在概念上被理解为一种相关插件的集合。

另外,也可以为publish提供第二个参数,该参数必须是一个数组,【array】,这个数组最终将被subscribe处理程序以单个命名参数的形式来接收!

[【一个常见的错误,就是忘记传递给dojo.publish数据必须要放入数组中,而dojo.subscribe的处理程序是以单个参数的形式来接收这些参数】] 下面稍加修改,示范一下dojo.unsubscribe的取消订阅。

dojo.unsubscribe取消订阅

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>     <script type="text/javascript" src="js/dojo/dojo.js"></script>     <script type="text/javascript">         function Tom(topic) {             this.topic = topic;             this.hello = function () {                 alert("Hello,I'm Tom!");
//Tom直接发布信息,不针对某个具体的目标 dojo.publish(this.topic); } }
function Jerry(topic) { this.topic = topic; this.hello = function () { alert("Hello,I'm Jerry");
//取消订阅,handle dojo.unsubscribe(this.handle); }
//dojo.subscribe返回一个句柄handle this.handle = dojo.subscribe(this.topic, this, "hello"); }
var tom = new Tom("/hello"); var jerry = new Jerry("/hello");
</script> </head> <body>
<button onclick="tom.hello();">click me</button> </body> </html>

第一次点击按钮的时候,会弹出tom的"Hello,I'm Tom!",和jerry的"Hello,I'm Jerry",

然后再点击按钮,由于取消了订阅,将只会弹出tom的"Hello,I'm Tom!",而jerry不会再对/hello这个主题作回应了,因为他已经取消对这个主题的订阅了。

dojo.connectPublisher

最后还有一种可能的情况,假设你不确定是否可以修改Tom的hello方法,以便在其中包括对dojo.publish的调用,也许是因为存在禁止这样做的外部限制,或者那些代码一开始不是你编写的,不过,无论怎么样也无需担心,此时可以使用另外一个方法,就是 dojo.connectPublisher ,让它在特定时间发生时负责向我们发布通知:

function Tom() {     this.hello = function () {         alert("Hello,I'm Tom!");     } }
function Jerry() { this.greet = function () { alert("Hello,I'm Jerry"); } }
var tom = new Tom(); var jerry = new Jerry();
var topic = "/SayHi";
dojo.subscribe(topic, jerry, "greet"); dojo.connectPublisher(topic, tom, "hello");
tom.hello();

【注意:事实上,connectPublisher的后台工作原理就是每当特定的函数被调用时,就通过dojo.connect在该函数调用与dojo.publish调用之间建立一个连接】

dojo.publish 和 dojo.subscribe的更多相关文章

  1. Dojo入门:dojo中的事件处理

      JS为DOM添加事件 在原生的环境下,为DOM添加事件处理函数有多种方法: <input type="button" name="btn" value ...

  2. dojo 十 ajax dojo/_base/xhr

    官方教程:Ajax with DojoAjax功能:1.从服务器加载静态数据2.从web服务中访问xml或json类型的数据3.将表单(form)数据发送到服务器4.刷新页面内容....Ajax在RI ...

  3. dojo 九 effects dojo/_base/fx 和 dojo/fx

    官方教程:Dojo Effects这里讲学习一下dojo如何实现淡入.淡出.滑动等效果.实现这些特殊的效果有两个包 dojo/_base/fx 和 dojo/fx.dojo/_base/fx 中提供了 ...

  4. DOJO 八 event dojo/on

    官网教程:Events with Dojo在元素上绑定events,需要引用包dojo/on,通过on方法来实现. <button id="myButton">Clic ...

  5. dojo.byId、dojo.query、dojo.attr

    概述: dojo.byId(/*string*/id或/*DomNode*/node) 1.传入DOMNode返回传入的domNode; 2.传入id返回id为当前值的domNode dojo.que ...

  6. Dojo API中文 Dojo内容模块概览,初学者

    官网:http://dojotoolkit.org/reference-guide/1.10/dojo/index.html#dojo-dojo的翻译 dojo 内容: dojo dojo/dojo ...

  7. dojo.js --dojo Quick Start/dojo入门手册1

    我看了http://www.cnblogs.com/mylem/archive/2009/11/11/1600984.html这篇博客以后 ,就开始设计自己的代码,其实很多解释都是在我的代码里,所以就 ...

  8. dojo 官方翻译 dojo/aspect

    官网地址:http://dojotoolkit.org/reference-guide/1.10/dojo/aspect.html after() 定义:after(target, methodNam ...

  9. dojo 官方翻译 dojo/_base/lang 版本1.10

    官方地址:http://dojotoolkit.org/reference-guide/1.10/dojo/_base/lang.html#dojo-base-lang 应用加载声明: require ...

随机推荐

  1. 100m和1000m网线的常见制作方法

    100m和1000m网线的常见制作方法 100m和1000m网线的常见制作方法: 5类线(100m)的制作: a: 绿白(3).绿(6).橙白(1).蓝(4).蓝白(5).橙(2).棕白(7).棕(8 ...

  2. js数组转置

    <script type="text/javascript">     var arr=[[1,2,3],[4,5,6],[7,8,9],[17,18,19]];    ...

  3. MySQL字符集转换引发插入乱码问题

    根据http://www.cnblogs.com/cchust/p/4601536.html进行验证测试 问题背景 在mysql上面执行一条普通的insert语句,结果报错: Incorrect st ...

  4. .NET后台如何获取前台HMTL控件的值

    很多时候我们需要HTML控件,感觉比服务器控件更加简介,清爽,那么如何获取HMTL控件的值呢,请看下面例子: 前台页面代码: <input id="Text1" type=& ...

  5. Centos7 ZooKeeper 安装过程

    www.apache.org/dist/上可以下载Hadoop整个生态环境的组件,我下的Zookeeper3.4.6版本 我一般都是在一个虚拟机上将一.二步都做完,然后克隆出来,再到克隆出来的虚拟机上 ...

  6. 字典树(codevs 4189)

    4189 字典  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 大师 Master 题解  查看运行结果     题目描述 Description 最经,skyzhong得到了 ...

  7. 直接放个DB2 SQL STATEMENT大全好了!

    SQL statements   This topic contains tables that list the SQL statements classified by type. SQL sch ...

  8. 1.2 容器-container

    1) *  容器是用于存放数据的类模板,实例化后就是容器类.用容器定义的对象称为容器对象. **类型相同的容器可以进行比较运算 2)分类 容器可分为顺序容器和关联容器两大类. *:顺序容器 元素的位置 ...

  9. hdu 1541 Stars

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1541 思路:要求求出不同等级的星星的个数,开始怎么也想不到用树状数组,看完某些大神的博客之后才用树状数 ...

  10. IDT5V49EE904资料学习

    一.特性: 1.4个内部PLL 2.内部非易失EEPROM. 3.最快400k的I2C串行接口. 4.输入时钟范围:1M—200M. 5.输出时钟范围:4.9k—200M 6.输入晶振参数带有在线可编 ...