`
lengyun3566
  • 浏览: 452537 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
D59180b9-02f1-3380-840c-ea34da46143c
《Spring Secur...
浏览量:383422
社区版块
存档分类
最新评论

dojo的connect方法实现及源码剖析(实现JS上的类似AOP效果)

 
阅读更多

dojo是功能非常强大的JavaScript类库,论类库本身的功能,丝毫不逊色于jQuery,但是jQuery的轻量级和丰富的插件使其在互联网领域风生水起,知名度要高得多。dojo也提供了自己的组件库,名为dijit,它们拥有统一的生命周期。dojo这几年也得到了很多大公司的支持,并应用与很多领域,如struts2就使用了它,通过研究dojo的使用方式和源码对提升前台的开发能力大有益处。

dojo实现了强大的类继承机制,并对常用的前台功能进行了很多封装,使得我们在进行开发时不必费工夫去直接接触HTML和CSS的一些用法,所以也就避免了一些浏览器兼容性的问题。

在本文中,将会介绍一个dojo提供的很有用的功能,使用这个功能一方面能够实现对dom元素事件的统一方式处理,另一方面还能够实现类似于Java中AOP的效果:在一个方法调用之后,执行另外的一系列方法。这个功能就是dojo的connect方法。

 

场景一:我有一个按钮,想在点击按钮的时候,触发一些事件处理

这样的场景,通过标准的js和html编码,也能很容易的实现,但是通过使用dojo提供的connect方法,将会使你的处理更轻松。

 

<input type="button" value="ss"  id="button"/>

 以上为一个按钮的定义,事件绑定和处理怎么写呢?

 

	dojo.addOnLoad(function(){
		dojo.connect(dojo.byId("button"),"onclick",test);
	})

	function test(){
		alert("我被点中啦!");
	}

 通过这么简单的配置,当你再次点击这个按钮的时候,test方法就会被调用了

场景二:我有一个方法名为test,我想在这个方法被执行的时候,另外一个方法test2也能被执行:

 

function test(){
	alert("first");
}
	
function test2(){
	alert("second");
}

 普通情况下,需要在test里面写上test2();这样这两个方法就紧密耦合在一起了。通过使用dojo的connect方法,可以很方便的实现该要求:

 

dojo.connect(null,"test",null,test2);

 这样在每次调用test的时候,test2都会被调用了。

 

那么这个功能是怎么实现的呢?看一下dojo的源码吧,这部分的实现是通过connect.js实现的:

 

dojo.connect = function(/*Object|null*/ obj,
						/*String*/ event,
						/*Object|null*/ context,
						/*String|Function*/ method,
						/*Boolean?*/ dontFix){
//以上前四个参数比较重要
//obj为原方法所在的对象,可以为空,为空的话就是全局的方法
//event必须为原方法或事件的名称,注意为字符串
//context为要添加方法的执行上下文,也就是在添加方法中this指的是什么
//method参数为要添加方法的引用

//在这个方法中,进行了一些参数处理后,通过这句话,完成实际的工作
return dojo._connect.apply(this, args);
}

dojo._connect = function(obj, event, context, method){
	var l=dojo._listener, h=l.add(obj, event, dojo.hitch(context, method));
	return [obj, event, h, l]; // Handle
//以上的代码中,l.add(obj, event, dojo.hitch(context, method));又是关键
};

//dojo._listener为一个简单对象,包含了两个重要的方法,分别是add和remove,我们重点关注add

	add: function(/*Object*/ source, /*String*/ method, /*Function*/ listener){
		//三个参数分别为目标对象,对象的方法名以及已经进行完上下文环境处理的待添加方法

		source = source || dojo.global;
		
		var f = source[method];//取到目标对象
		

		if(!f || !f._listeners){//如果目标方法没有_listeners属性

			var d = dojo._listener.getDispatcher();//调用此方法后其实返回的是一个全新的方法,对目标方法进行了封装
			
			d.target = f;//设置目标方法
			
			d._listeners = [];//保持了一个数组,记录了目标方法执行后要执行的其它方法
			
			f = source[method] = d;//注意此处将原来的方法进行了替换,你原来的目标方法已经被修改了
		}
		
		return f._listeners.push(listener); //将要添加的方法置于数组之中,并返回一个句柄
	}

//getDispatcher是很重要的辅助方法,它返回了一个function对象,替换了我们原来的目标方法
getDispatcher: function(){
		
		return function(){
			var ap = Array.prototype, c = arguments.callee, ls = c._listeners, t = c.target,
			//此处t就是我们原来的目标方法
				r = t && t.apply(this, arguments),//执行并记录返回值
			
				i, lls = [].concat(ls);

			//遍历数组中的每一个方法,依次执行,从而实现了类似AOP的功能
			for(i in lls){
				if(!(i in ap)){
					lls[i].apply(this, arguments);
				}
			}
			
			return r;//return原始方法的运行的结果值
		};
	}

 

通过以上的代码分析,可以了解到dojo实现该功能的核心思想是将原有的方法进行了替换,在新的方法中记录了原方法以及要添加的其他方法,在执行时,依次执行,实现的确实很高明。

 

4
0
分享到:
评论
4 楼 lengyun3566 2011-11-18  
houfeng0923 写道
Extjs 和 YUI 也有类似的功能。有空整理下跟你文章汇合

多谢关注,期待你的文章!
3 楼 houfeng0923 2011-11-17  
Extjs 和 YUI 也有类似的功能。有空整理下跟你文章汇合
2 楼 lengyun3566 2011-08-10  
dojotoolkit 写道
dojo 1.7里会有一系列叫dojo.aspect.after/dojo.aspect.before/dojo.aspect.around的方法,原理和connect类似,但更像AOP了。

今天早上更新了dojo的源码,果然如此,期待1.7的功能哈
1 楼 dojotoolkit 2011-07-15  
dojo 1.7里会有一系列叫dojo.aspect.after/dojo.aspect.before/dojo.aspect.around的方法,原理和connect类似,但更像AOP了。

相关推荐

    Dojo构建Ajax应用程序源码(包括书中用到的dojo-release-1.1.2)

    通过分析这个源码包,开发者不仅可以了解Dojo 1.1.2版本的具体实现,还能对比学习Dojo后续版本的改进和新特性。同时,对于想要深入了解Ajax开发或者JavaScript库构建的人来说,这是一个很好的学习资源。

    DOJO权威指南+DOJO1.1源码

    - **dojo/aspect**: 实现AOP(面向切面编程),提供方法的前置、后置、环绕和异常处理等通知功能。 - **dojo/store**: 用于管理数据存储,可以与各种数据源(如JSON、XML、Ajax等)交互。 4. **DOJO的UI组件...

    dojo的源码

    通过分析和学习Dojo的源码,开发者可以深入了解JavaScript库的设计模式,模块化实现,以及如何编写高效、可维护的前端代码。对于想要深入Dojo或者JavaScript的开发者来说,这是一个宝贵的资源。

    dojo china extjs 视频教程源码

    Dojo是一个全面的JavaScript工具包,提供了丰富的功能,包括模块化、UI组件、数据管理、动画效果等,旨在简化Web应用的开发。它以强大的模块系统和对AMD(Asynchronous Module Definition)规范的支持而闻名,这使得...

    dojo常用方法总结

    - **`dojo.connect`**:用于连接一个事件处理器到指定的DOM事件上。 ```javascript // 当id为"aa"的元素发生"onchange"事件时执行回调函数 dojo.connect(dojo.byId("aa"), "onchange", function() { console....

    dojo类机制实现原理分析

    通过以上分析,我们可以看到Dojo的类机制在实现上采用了JavaScript原生的原型链特性,并在此基础上增加了多重继承的支持。同时,为了确保多重继承中成员函数的访问顺序,Dojo引入了C3线性化算法,有效地解决了继承...

    dojo js dojo js

    dojo js dojo js dojo js dojo js dojo js dojo js dojo js

    dojo官网的源码dojo官网的源码

    Dojo 是一个强大的JavaScript工具库,它为Web开发提供了丰富的功能和组件,包括AJAX、DOM操作、动画效果、国际化、事件处理等。这个压缩包包含的是Dojo框架的1.4.2版本的源码,这是一个较早的版本,但仍然包含了许多...

    超多的Dojo实例应用演示源码

    Dojo 是一个强大的JavaScript工具库,它为Web开发提供了丰富的功能和组件,涵盖了从DOM操作、事件处理到AJAX通信、动画效果等各个方面。这个"超多的Dojo实例应用演示源码"压缩包显然是一个关于Dojo框架的实践教程...

    DOJO TableContainer实现表单布局.js

    DOJO TableContainer实现表单布局.js

    AJAX之Dojo实现登陆框

    Dojo是一个强大的JavaScript库,它提供了一系列丰富的功能,包括AJAX交互、DOM操作、动画效果等,使得开发人员能够更加高效地创建交互式的Web应用。 【描述】"AJAX之Dojo实现登陆框"的描述可能是指通过Dojo库中的...

    Dojo.js核心dojo的javaScript类库Dojo.js核心dojo的javaScript类库Dojo.js核心dojo的javaScript类库

    dojo.js.核心jsDojo.js核心dojo的javaScript类库Dojo.js核心dojo的javaScript类库Dojo.js核心dojo的javaScript类库Dojo.js核心dojo的javaScript类库

    精通Dojo 随书源码

    通过研究《精通Dojo》随书源码,开发者不仅可以学习到Dojo库的基本用法,还能理解其背后的实现逻辑,从而提升JavaScript编程技能,更好地应用在实际项目中。对于想要精通Dojo的开发者来说,这是一份不可多得的学习...

    dojo-release-1.9.0-src.zip dojo javascript库源码

    Dojo 是一个强大的JavaScript工具包,它为Web开发提供了丰富的功能和组件,包括DOM操作、事件处理、Ajax交互、动画效果、模块化编程等。在"dojo-release-1.9.0-src.zip"这个压缩包中,我们获取的是Dojo 1.9.0版本的...

    dojo中文文档-dojo手册

    Dojo的dojo.query方法类似于jQuery的选择器,用于选取页面中的DOM元素。此外,Dojo还提供了一套强大的DOM操作API,如dojo.create、dojo.destroy和dojo.style,使得在JavaScript中操作DOM变得简单易行。 在数据交互...

    dojo dojo实例 dojo例子 dojo资料 dojo项目 dojo实战 dojo模块 dojo编程

    7. **dojo/aspect**:提供面向切面编程(AOP)的支持,允许在方法调用前、后或替代方法执行插入额外的功能。 8. **dojo/data**:提供了一种数据模型接口,用于与各种数据源进行交互,比如从服务器获取数据。 9. **...

    dojo例子 各方法的用法

    Dojo 是一个强大的JavaScript工具库,它为Web开发提供了丰富的功能和组件,涵盖了从DOM操作、数据处理到AJAX通信等多个方面。在这个"dojo例子 各方法的用法"的压缩包中,我们很可能会找到关于如何使用Dojo库的各种...

    struts2+dojo实现例子

    在这个例子中,可能使用了Dojo的`dojoContentPane`或者`dijit.form.Form`等组件,配合`dojo.connect`或`dojo.on`监听用户交互事件,然后使用`xhr`方法与后台Struts2 Action进行通信。 Struts2与Dojo的集成通常涉及...

    dojo源码

    5. Dojo对象系统:Dojo使用`dojo/_base/lang`中的`lang.getObject`和`lang.extend`方法来实现面向对象编程。`getObject`用于根据路径创建或获取对象,`extend`则用于类的继承。 6. Dojo DOM操作:`dojo/dom`模块...

    dojo事件处理框架

    通过`dojo.event.connect()`方法,我们可以将事件处理函数与DOM元素及事件类型关联起来,如: ```javascript var buttonNode = document.getElementById("button"); dojo.event.connect(buttonNode, "onclick", ...

Global site tag (gtag.js) - Google Analytics