原文链接: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. android通过BitmapFactory.decodeFile获取图片bitmap报内存溢出的解决办法

    android通过BitmapFactory.decodeFile获取图片bitmap报内存溢出的解决办法 原方法: public static Bitmap getSmallBitmap(Strin ...

  2. Mac下安装MySQL

    2015-07-13 15:10:32 Mac下用homebrew安装软件还是很方便的 brew install mysql 等待一会儿安装完毕后到安装目录: /usr/local/Cellar/my ...

  3. ACM/ICPC 之 差分约束系统两道(ZOJ2770-POJ1201)

    当对问题建立数学模型后,发现其是一个差分方程组,那么问题可以转换为最短路问题,一下分别选用Bellmanford-SPFA解题 ZOJ2770-Burn the Linked Camp //差分约束方 ...

  4. suse11 sp2 搭建openvpn

    什么是VPN IP机制仿真出一个私有的广域网"是通过私有的隧道技术在公共数据网络上仿真一条点到点的专线技术.所谓虚拟,是指用户不再需要拥有实际的长途数据线路,而是使用Internet公众数据 ...

  5. 【python】getopt使用

    来源:http://blog.chinaunix.net/uid-21566578-id-438233.html 注意对比:[python]argparse模块 作者:limodou版权所有limod ...

  6. 【Git】标签管理

    来源:廖雪峰 为什么要标签: 发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本.将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来. ...

  7. 【网络】VPN和代理服务器的区别

    来自:http://www.zhihujingxuan.com/19311.html [scotttony的回答(41票)]: VPN和ssh哪个比较好, 要看你怎么定义是“好”. ssh作为一个创建 ...

  8. HDU 5995 Kblack loves flag ---BestCoder Round #90

    题目链接 用两个布尔数组分别维护每个行/列是否被插过旗帜,最后枚举每一行.列统计答案即可.空间复杂度O(n+m),时间复杂度O(n+m+k). #include <cstdio> #inc ...

  9. 由浅入深剖析.htaccess

    转自:http://blog.csdn.net/21aspnet/article/details/6908025 [-] htaccess文件使用前提 htaccess基本语法介绍 现学现用学习正则表 ...

  10. ssh配置免密码登录

    日常工作中很多情况下都需要登录服务器进行管理,一般都是用ssh进行连接,为了防止密码外泄,可以配置下ssh的免密码登录. 首先服务器两台: A:43.224.34.* B:104.238.161.* ...