YUI3沙盒下的多模块交互实践

看了 NCZ 的 scalable-javascript-application-architecture 后对YUI3的沙盒设计以及模块管理有了更深的理解,尤其其中的模块交互方式非常有趣。


传统模式:


以前使用ext,jquery的多模块交互模式:


页面两个模块 m ,m2 ,当 m 变化时需要通知 m2 更新自己的相关状态。

 

var m=new Module1();
var m2=new Module2();
m.on("change",function(e){
   m2.update(...);
});

m.fire("change","hello");

 

耦合问题:

由以上代码可见,m ,m2实际上已经耦合在一起,它们必须出现在页面的相同位置,并且如果需求变化去除了m2,则m1.on也必须去除。



YUI3事件解耦方式:


YUI3事件引入了bubble以及broadcast模式,尤其broadcast,可以将事件传递到全局事件空间,其他模块只要监听全局事件即可,去除了和某一模块的耦合性。


修正版:

 

YUI({
			filter:"DEBUG"
			}).use("base","event","node","event-simulate","event-custom","node-event-simulate","plugin","oop","pluginhost",function(Y){
			function Module1(){
				Module1.superclass.constructor.call(this);
				this.publish("change",{
					emitFacade:true,
                                        //该事件需要bubble到全局空间
					broadcast:2
				});
			}
			
			Module1.NAME="Module1";
			
			Y.extend(Module1,Y.Base);
			
			var change=Y.one("#trigger");
			var m=new Module1();		
			change.on("click",function(){
				m.fire("change","hello");
			});
			
		});
		
		
		
		YUI({
			filter:"DEBUG"
			}).use("base","event","node","event-simulate","event-custom","node-event-simulate","plugin","oop","pluginhost",function(Y){
			function Module2(){
				
                               Module2.superclass.constructor.call(this);
			}
			
			Y.extend(Module2,Y.Base,{
				update:function(args){
					alert("Module2 knowns Module1's change :"+args);
				}
			});
			
			var m=new Module2();
			//另一模块只需监听某模块发布到全局空间的change事件,并更新自己状态
			Y.Global.on("Module1:change",function(e){
			
				m.update(e.details);
				
			});
			
			
			
		});
 

则可见 模块1,模块2边界非常清晰,可以根据需求变化随意去除任一模块,系统更具灵活性。



PS:事件的前缀机制


首先可以看事件机制的详细解释 ,在上述例子中,我们看到了 Global监听的事件为Module1:change,而不是普通的change,而这个Module1正是module1类的名字配置,EventTarget中有prefix的机制,但是平常直接augment,EventTarget时这个机制是没有对应开启功能,当从Base继承时,Base初始化自己的事件机制的prefix为配置的类名:

 

//init: 
this._yuievt.config.prefix = this._eventPrefix=this.constructor.EVENT_PREFIX || this.constructor.NAME;;

 那么在 EventTarget功能代码中,每次进行on以及fire都会检查是否存在prefix,如果绑定的参数为eventName形式,会被补全为prefix:eventName的形式,prefix默认为自己的prefix

 

var parts = _parseType(type, this._yuievt.config.prefix)
//加入前缀标识
type=parts[1];

 可见如果单单监听change事件,则实际效果为监听自身的change,而如果要监听某类对象的change,这正是prefix发挥余地的地方,也避免了多类对象同名事件的混淆。

 

 

参考资料:

 

2010-10-21 新瓶老酒:managing javascript object

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值