dojo.publish 和 dojo.subscribe
原文链接: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的更多相关文章
- Dojo入门:dojo中的事件处理
JS为DOM添加事件 在原生的环境下,为DOM添加事件处理函数有多种方法: <input type="button" name="btn" value ...
- dojo 十 ajax dojo/_base/xhr
官方教程:Ajax with DojoAjax功能:1.从服务器加载静态数据2.从web服务中访问xml或json类型的数据3.将表单(form)数据发送到服务器4.刷新页面内容....Ajax在RI ...
- dojo 九 effects dojo/_base/fx 和 dojo/fx
官方教程:Dojo Effects这里讲学习一下dojo如何实现淡入.淡出.滑动等效果.实现这些特殊的效果有两个包 dojo/_base/fx 和 dojo/fx.dojo/_base/fx 中提供了 ...
- DOJO 八 event dojo/on
官网教程:Events with Dojo在元素上绑定events,需要引用包dojo/on,通过on方法来实现. <button id="myButton">Clic ...
- dojo.byId、dojo.query、dojo.attr
概述: dojo.byId(/*string*/id或/*DomNode*/node) 1.传入DOMNode返回传入的domNode; 2.传入id返回id为当前值的domNode dojo.que ...
- Dojo API中文 Dojo内容模块概览,初学者
官网:http://dojotoolkit.org/reference-guide/1.10/dojo/index.html#dojo-dojo的翻译 dojo 内容: dojo dojo/dojo ...
- dojo.js --dojo Quick Start/dojo入门手册1
我看了http://www.cnblogs.com/mylem/archive/2009/11/11/1600984.html这篇博客以后 ,就开始设计自己的代码,其实很多解释都是在我的代码里,所以就 ...
- dojo 官方翻译 dojo/aspect
官网地址:http://dojotoolkit.org/reference-guide/1.10/dojo/aspect.html after() 定义:after(target, methodNam ...
- dojo 官方翻译 dojo/_base/lang 版本1.10
官方地址:http://dojotoolkit.org/reference-guide/1.10/dojo/_base/lang.html#dojo-base-lang 应用加载声明: require ...
随机推荐
- action 方法的访问
Action中的方法的访问: 访问Action的中的方法,默认情况下只能访问execute方法.那么多次请求就不能提交到一个Action.能不能一个模块的多次请求提交到一个Action中? * 需要使 ...
- docker进入容器的方式
通过docker创建守护运行(在使用-d参数时)的容器时,容器启动后会进入后台.用户无法看到容器中的信息.某些时候如果需要进入容器进行操作,有多种方法,包括使用docker attach命令.dock ...
- Qt 文件处理
1.删除目录下所有的文件 void deleteAllFiles(const QString& fileDir) { QDir dir(fileDir); if(!dir.exists()) ...
- java web 学习 --第一天(Java三级考试)
1.Servlet servlet是运行在web server或 application server端的Java程序,主要用于在服务器端产生动态内容. servlet 在服务器端主要有以下作用 读取 ...
- 使用iScroll时,input等不能输入内容的解决方法
做移动平台的应用,使用iscroll使屏幕上下滑动.发现当使用iscroll后,input等不能输入内容了.只要在iscroll.js文件中加入如下代码就ok了. function allowForm ...
- 【leetcode】 Letter Combinations of a Phone Number(middle)
Given a digit string, return all possible letter combinations that the number could represent. A map ...
- 将txt多行文本合并成一行
1.用word打开txt文本2.打开“替换”功能,查找内容“^p”,替换内容为“,”(均无双引号).即可把多列文字合并为一行.
- August 11th 2016, Week 33rd Thursday
A particular fine spring came around. 转眼又是一番分外明媚的春光. Hey, it is hot outside, sometimes even unbearab ...
- WEB前端开发学习:源码canvas 雪
WEB前端开发学习:源码canvas 雪 双旦节要到了,程序员们为了响应气氛,特别用代码制作了动态雪花,WEB前端开发学习的初学者们一起跟着案例做一遍吧! <!DOCTYPE html> ...
- Centos以rpm方式进行安装MySql
安装过很多次mysql了,却没好好总结过,每次安装完了都忘,下次还要重新Google,这次总结下,自己以后也有的查. 1.安装采用的的rpm包的方式,安装前要先看系统内是否安装了旧版本的MySql和m ...