与其他模块的通信
在实现一个模块之后,它会和其他模块进行交互。传统的方法是紧耦合(通过Nicholas Zakas的视频中我们可以了解什么是紧耦合什么是松耦合),也就是通过方法调用和属性赋值来将这些模块紧密联系在一起,在这儿就不赘述了。下面我们介绍另一种方法——自定义事件,Y.Base里面包含了你所需要的全部方法。
首先,在initializer中,你要发布这个自定义事件,让大家都知道它: initializer: function (cfg) { this.publish(‘eventName’, { /*… options … */}); },
需要注意的是,事件名称最好是一个常见单词,因为在后面你会经常使用它,常见单词可以避免出现拼写错误。然后,假设你拥有一个对象,例如: var myWidget = new Y.MyWidget({ /* .. attributes … */ });
此时,你可以为它绑定事件: myWidget.after(‘eventName’, this._eventNameListener, this);
然而,这样做虽然不像直接的方法调用那样联系紧密,但是由于必须有一个myWidget的实例,所以其实质还是紧耦合。也就是说,在两个模块的通信中,一个模块必须知道另一个的细节,或者存在一个监视模块为它们建立连接。在这个过程中,有两个配置项是非常重要的,broadcast和emitFacade。
第一个,broadcast,可以让你在其他的模块中为这个事件设置监听器。broadcast默认值为0,此时只能用前面所示的那个方法。如果希望事件可以在任何地方被监听,你需要改变broadcast的值。如果只是在沙箱内,broadcast值为1,如果需要在各个沙箱间,则broadcast值为2。一个沙箱如下所示: YUI().use( ‘module1′, …, ‘moduleN’, function (Y) { // this is your sandbox });
在页面中可以有多个这样的沙箱: YUI().use( ‘module1′, …, ‘moduleN’, function (Y) { // this is your sandbox }); YUI().use( ‘moduleX-1′, …, ‘moduleX-N’, function (Z) { // this is another sandbox });
如果你设置broadcast值为2,你就可以在沙箱2中监听在沙箱1中发布的事件,具体细节请看Event user guide。我们继续讨论简单沙箱的情况。
要在一个沙箱内监听另一个模块中发布的事件,必须知道的是这个模块的静态属性NAME的值和事件名称。回想下,Y.Base.create方法所带的第一个参数的值,就是NAME属性的值。因此,如果你创建了这样一个模块: Y.MyWidget = Y.Base.create( ‘xxxx’, Y.Widget, // … and so on
然后在initializer发布了一个’help’事件: initializer: function (config) { this.publish(‘help’, { broadcast: 1, emitFacade: true }); },
那么,要在其他模块的沙箱内监听这个事件,就可以这样做: Y.after(‘xxxx:help’, function (ev) { … }, this);
在这里调用了Y.after,而不是myWidget.after,所以我不再需要一个实例才能触发这个事件。你也可以用同样的方法来监听DOM事件或者其他的自定义事件,比如’valueChange’等,不同的仅仅是引号前面的前缀。你也可以使用别的东西作为前缀,Y.base会接受这个值,但是通常情况下,Y.base提供的默认值已经足够了。你还需要设置emitFacade值,因为需要一个对象来触发事件,从而为ev.target提供门面值(facade value)。也许你会想,如果监听器所在的模块获得了注册事件模块的对象,那不是重新成为紧耦合了么。但事实并非如此,只要你在监听器模块中不保留这个对象,耦合就不复存在。此外,我们还有更好的办法。
出处:Taobao.com UED Team
责任编辑:bluehearts
上一页 使用YUI 3开发Web应用的诀窍 [6] 下一页 使用YUI 3开发Web应用的诀窍 [8]
◎进入论坛网页制作、WEB标准化版块参加讨论,我还想发表评论。
|