麻雀虽小,五脏俱全:用DOJO写一个最简单的控件

时间:2021-10-09 22:45:53
现在javascript框架、控件库有很多,JQuery、Ext、prototype、MooTools、DOJO,
这些都是在Google上搜索“javascript+framework”列在第一页的。

这其中,除了MooTools,其它的都有所了解,但只在项目中用过Ext和DOJO。
但一直不太喜欢Ext,性能有问题,新的版本还收费了,
特别讨厌这种打着开源旗号赚钱的,像JGraph,JEP,被忽悠进来套住你就开始收费,

另外,Ext官方提供的例子都是用JS来创建和初始化控件,一个JS配套一个HTML来用,
这样管理起来很混乱。我认为官方例子应该是Best Practice,所以不太接受这种模式。


DOJO在我眼里是一个缺点和优点都很突出的家伙
缺点:
1、文档非常之差
2、CodeBase非常之大(优点乎,缺点乎?)
3、版本演进快,且每次版本演进,都有大量的API发生变化,还不够成熟

优点:
1、是一个很优秀的控件开发框架
2、完全体现了javascript面向对象的一面


EXT和DOJO比起来,我觉得EXT是一个控件库,而DOJO是一个框架
我06年第一次接触DOJO,当时版本0.3.X,今天项目中又有需求想用DOJO,版本是1.3.1,
对比0.3和1.3,发现核心的思路并没有太大变化,但出厂提供的控件却有翻天覆地的变化,
不过已经先入为主的对它的控件有成见,导致现在也没有兴趣再去研究,
还是讲讲如何拿DOJO做自定义的控件吧。

---

DOJO很复杂,但我们可以简单的认为它分三层
1、最底层的是核心API
核心API提供的方法简化了DOM、字符串、CSS、事件等相关的操作。
核心API还实现了类似于Java的package概念和import机制,方便了代码组织和依赖管理。

2、基于核心API,创造了“控件生命周期”概念
这是DOJO的亮点,允许第三方以规范的方式开发控件。
基于DOJO开发的控件具有很强的内聚性和面向对象的特性。

3、基于2所开发的各类控件
DOJO自己提供的控件也比较全了,只是由于历史原因,没有深入研究过。

---

DOJO的控件统称DIJIT,要写出DOJO版的Hello World控件,你需要了解的知识并不太多:
1、一个控件就是一个JS类
2、所有的控件都继承自_Widget或其子类,_Widget类提供了控件的生命周期管理函数
3、可以同时继承_Templated,继承该类,可以为控件绑定模板来描述控件的展示


关于_Widget基类的介绍
1、生命周期方法
_Widget提供了一系列方法称为“生命周期方法”,DOJO框架在初始化一个控件的时候,会依次调用它们,
我们的自定义控件,可以重写特定的方法来加入自己的初始化逻辑,方法调用顺序及说明:
preamble(/*Object*/ params, /*DOMNode*/node)
    //这是一个通常不会用到的方法,这个方法的返回值,作为constructor的输入参数param
constructor(/*Object*/ params, /*DOMNode*/node)
    // 这个方法相当于java类的构造函数
    // 在这个类中执行初始化动作    
postscript(/*Object*/ params, /*DOMNode*/node)
    //实际的控件创建过程,依次调用如下方法(都可以被重写)
    _Widget.create(/*Object*/params, /*DOMNode*/node)
    _Widget.postMixInProperties( )
    _Widget.buildRendering( )
    _Widget.postCreate( )
    //我用得最多的是postCreate方法,这个方法中,控件已经初始化完毕,界面上也已经显示出来了,
    //通常在这个方法中启动业务相关的处理


2、该类的几个重要属性(控件可以通过this访问)
    id:         控件被授予的唯一编号,如果用户不指定,则DOJO随机创建一个
    domNode:    该控件在HTML中对应的DOM节点
    


最基本的自定义控件示例:
js文件:./hello/world.js(以下涉及到文件名,都用相对路径,其中./代表和"dojo,dijit,dojox"同级目录)
//声明自己输出的类名
dojo.provide("hello.world");
//声明自己依赖的类名
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");

//dojo.declare定义控件类,第一个参数:类名,第二个参数:父类数组,第三个参数:类的prototype
dojo.declare("hello.world",[dijit._Widget,dijit._Templated],
{
    postCreate:function(){
        this.domNode.innerHTML="hellow world";
    } 
}
);


该控件的行为极其简单,在postCreate方法中,将自己在HTML页面中对应的DOM节点的内容设置为 hellow world

html文件:./helloworld.htm
<html>
<head>
<title>Hello World</title>
<!-- 首先引入dojo.js,modulePaths用来定义包含控件的js目录,类似于jsp的自定义tag引入的机制-->
<script type="text/javascript" src="./dojo/dojo.js" djConfig="parseOnLoad:true,modulePaths:{hello:'../hello'}">
</script>

<script type="text/javascript">
    dojo.require("dojo.parser");
    dojo.require("hello.world"); //引入自定义控件
</script>
</head>
<body>
    <div dojoType="hello.world"></div>
</body>
</html>


modulePaths的具体作用和用法,请google即可。



接下来,我们将控件参数化
我们可以在写标签的时候,将名字作为参数传进去,然后控件显示HELLO XXX,
首先将html文件改成:
<html>
<head>
<title>Hello World</title>
<!-- 首先引入dojo.js,modulePaths用来定义包含控件的js目录,类似于jsp的自定义tag引入的机制-->
<script type="text/javascript" src="./dojo/dojo.js" djConfig="parseOnLoad:true,modulePaths:{hello:'../hello'}">
</script>

<script type="text/javascript">
    dojo.require("dojo.parser");    
    dojo.require("hello.world");
</script>
</head>
<body>    
    <div dojoType="hello.world" yourName="jinxfei"></div>
</body>
</html>


大家注意到,我们在标签上增加了“ yourName”属性,在控件中如何使用该属性呢?
可以在construtctor方法中接收此属性的值,将值赋给控件类自身的变量,然后在postCreate中使用,
js代码如下:
dojo.provide("hello.world");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");


dojo.declare("hello.world",[dijit._Widget,dijit._Templated],
{
    yourName:'world',
    constructor:function(params,node){
        this.yourName=params.yourName;        
    },
    postCreate:function(){
        this.domNode.innerHTML="hellow "+this.yourName;
    } 
}
);




接下来,我们将进一步增加控件进的复杂性
增加一个输入框,在这个输入框中输入文本的同时,动态更新hello XXX,
这就要用到dojo的事件绑定机制,最常用的模式为:
dojo.connect(node,event,obj,method);
表示将obj的method方法作为domNode的event事件处理函数,
例如:
dojo.connect(inputText,"onkey",this,"updateHello");

这次先改控件,在postCreate的时候,动态增加一个输入框,并为输入框动态绑定事件:
dojo.provide("hello.world");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");


dojo.declare("hello.world",[dijit._Widget,dijit._Templated],
{
    yourName:'world',
    typeIn:null,
    echoDiv:null,
    constructor:function(params,node){
        this.yourName=params.yourName;        
    },
    postCreate:function(){
        
        this.typeIn=document.createElement("input");
        
        this.typeIn.type="text";        
        this.domNode.appendChild(this.typeIn);        
        this.echoDiv=document.createElement("div");
        this.domNode.appendChild(this.echoDiv);
        dojo.connect(this.typeIn,"onkeyup",this,"updateHello");//动态绑定事件        
        this.updateHello();//调用方法初始化一下,先显示一个空的hello
    } ,
    updateHello:function(){
        this.echoDiv.innerHTML="hello "+this.typeIn.value;
    }
}
);


而HTML文件中对控件的引用,不用做任何改变(严格来讲,你需要删除yourName="jinxfei"这个属性)。

从这个稍微有一点点复杂的控件,我们已经可以看出 DOJO的优势
真正的面向对象!
控件管理范畴内的DOM元素,都可以放在类中作为属性来使用(直接用this.xxx引用),
这样,避免了document.getElementByID()满天飞,控件是内聚的。
响应事件的方法也是类的方法,免得在页面中声明大量的离散function,不好管理。


我先歇歇,接下来整理一下DOJO的模板机制,用模板做复杂控件更容易一些,
还有与DWR的结合等等。

44 个解决方案

#1


学习了

#2


学习要认真。

#3


个人认为,如果要在一个项目开始时引入一个JS框架来节省开发时间也好,增强页面效果也好,如果时间不是很充裕的话,我会选择用JQUERY,个人认为有以下几个好处

1.没有牵扯大量面向对象理论,写出来的代码可以很过程式,易维护
2.简单易学,一天就上手
3.插件多

然后EXT收费之后我对其除了鄙视还是鄙视

#4


引用 2 楼 jinxfei 的回复:
学习要认真。

学习中。。呵呵!!

#5


学习了


#6


学习中

#7


看的不是很懂

#8


shenm 

#9


现在用ext  更偏向于用ext  dojo看着臃肿

#10


引用 9 楼 scofic 的回复:
现在用ext  更偏向于用ext  dojo看着臃肿


非也,DOJO其实很简单。

#11


引用 3 楼 myairland 的回复:
个人认为,如果要在一个项目开始时引入一个JS框架来节省开发时间也好,增强页面效果也好,如果时间不是很充裕的话,我会选择用JQUERY,个人认为有以下几个好处 

1.没有牵扯大量面向对象理论,写出来的代码可以很过程式,易维护 
2.简单易学,一天就上手 
3.插件多 

然后EXT收费之后我对其除了鄙视还是鄙视


呵呵,先共同鄙视以下EXT!

JQUERY确实很好,设计思想很独到,
JQUERY让我想起了LISP语言。

#12


引用 11 楼 jinxfei 的回复:
引用 3 楼 myairland 的回复:
个人认为,如果要在一个项目开始时引入一个JS框架来节省开发时间也好,增强页面效果也好,如果时间不是很充裕的话,我会选择用JQUERY,个人认为有以下几个好处 

1.没有牵扯大量面向对象理论,写出来的代码可以很过程式,易维护 
2.简单易学,一天就上手 
3.插件多 

然后EXT收费之后我对其除了鄙视还是鄙视 



呵呵,先共同鄙视以下EXT! 

JQUERY确实很好,设计思想很独到, 
JQUERY让我想…


竟然不能回帖了。。。。。 家里这几天的网速超慢,

刚工作的时候都是自己写js的,刚开始的时候那个痛苦,再加上闭包什么的,搞的头大。后来就开始用prototype感觉很好用

现在转到JQuery了,感觉JQuery更方便了。只是有的时候觉得这样傻瓜的框架会不会让自己变得堕落。所以有的时候还自己尝试着写一些js代码和闭包。

DOJO一直都没用过,这帖子得先收藏一下,呵呵。

#13


奔来看看。。。

#14


引用 12 楼 kokobox 的回复:
引用 11 楼 jinxfei 的回复:
引用 3 楼 myairland 的回复: 
个人认为,如果要在一个项目开始时引入一个JS框架来节省开发时间也好,增强页面效果也好,如果时间不是很充裕的话,我会选择用JQUERY,个人认为有以下几个好处 

1.没有牵扯大量面向对象理论,写出来的代码可以很过程式,易维护 
2.简单易学,一天就上手 
3.插件多 

然后EXT收费之后我对其除了鄙视还是鄙视 


呵呵,先共同鄙视以下EXT! 

JQUERY确实很好,设计…


你都收藏啦,感谢支持,呵呵。

#15


也鄙视一下收费的EXT。
ext是比较强大,但是有点大,还有就是有很多BUG

#16


学习了

#17


jquery比较好使,他的连缀,隐式迭代,大量的开源控件。。。不使用,不行啊。

#18


好文,我也收藏了

#19


收藏

#20


收藏,慢慢学习!

#21


楼主的文章是播种机

收藏了

#22


强烈支持!!!

#23


谢谢。。。。。。。。

#24


只用过JQuery 麻雀虽小,五脏俱全:用DOJO写一个最简单的控件

#25


ext 居然還收費﹐以前玩過一點點﹐鄙視它﹗
 
jquery 比較好﹗

頂﹗﹗

#26


项目正在用dojo,感觉这几个框架中,这个还是比较复杂的。jquery个人比较喜欢

#27


麻雀虽小,五脏俱全:用DOJO写一个最简单的控件还是自己写的好点!用一两年框架,连js 是什么都忘了

#28


dojo主要的优点体现在他的数据绑定,在js中实现了组件的mvc.
至于所说的jquery的过程式编程优点,dojo提供了dojo.query()方法予以支持.当初设计时不用$也是考虑到命名空间的问题.

#29


引用 15 楼 fejay 的回复:
也鄙视一下收费的EXT。 
ext是比较强大,但是有点大,还有就是有很多BUG


是啊,现在被那些BUG搞死了

#30


该回复于2009-07-01 21:37:17被版主删除

#31


该回复于2009-07-01 17:16:39被版主删除

#32


问一下楼主,怎么把java代码html,sql代码放入博客中,并格式化,我的意思就是说那些代码高亮在网页中的实现

#33


楼上的,不太清楚哦。

我只知道,CSDN的论坛有专门的代码标记,blog好像没有。

#34


JS控件,个人倾向于jquery,DOJO还没用过,学习了!

#35


暂时还没精力去学习,但是很感兴趣

#36


dojo的学习曲线是最大的,比MFC还费劲。。。

#37


z xuexi.

#38


引用 36 楼 healer_kx 的回复:
dojo的学习曲线是最大的,比MFC还费劲。。。


实际上还好,跟MFC比,那小巫见大巫了,只是DOJO文档不好,这一点让人头疼。

#39


用你最初版本的hello/world.js+helloworld.htm跑出来页面报错,错误信息为:_5 is null
[Break on this error] (35 out of range 16) dojo.js (第 35 行)
我用的是dojo-release-1.4.0rc2,请问如何解决?

#40


jquery 多好啊

#41


不会 明天看看

#42


LZ
 dojo.connect(this.typeIn,"onkeyup",this,"updateHello");//这行代码可能会引起 IE的内存泄漏
修改为
 this.connect(this.typeIn,"onkeyup",updateHello);//这个应该可以
_widget基类中定义了connect销毁的时候会把事件处理函数置为null解决内存泄漏

#43


"缺点:文档非常之差"
Can't agree more!

#44


开源与收费是两码事吧?

#1


学习了

#2


学习要认真。

#3


个人认为,如果要在一个项目开始时引入一个JS框架来节省开发时间也好,增强页面效果也好,如果时间不是很充裕的话,我会选择用JQUERY,个人认为有以下几个好处

1.没有牵扯大量面向对象理论,写出来的代码可以很过程式,易维护
2.简单易学,一天就上手
3.插件多

然后EXT收费之后我对其除了鄙视还是鄙视

#4


引用 2 楼 jinxfei 的回复:
学习要认真。

学习中。。呵呵!!

#5


学习了


#6


学习中

#7


看的不是很懂

#8


shenm 

#9


现在用ext  更偏向于用ext  dojo看着臃肿

#10


引用 9 楼 scofic 的回复:
现在用ext  更偏向于用ext  dojo看着臃肿


非也,DOJO其实很简单。

#11


引用 3 楼 myairland 的回复:
个人认为,如果要在一个项目开始时引入一个JS框架来节省开发时间也好,增强页面效果也好,如果时间不是很充裕的话,我会选择用JQUERY,个人认为有以下几个好处 

1.没有牵扯大量面向对象理论,写出来的代码可以很过程式,易维护 
2.简单易学,一天就上手 
3.插件多 

然后EXT收费之后我对其除了鄙视还是鄙视


呵呵,先共同鄙视以下EXT!

JQUERY确实很好,设计思想很独到,
JQUERY让我想起了LISP语言。

#12


引用 11 楼 jinxfei 的回复:
引用 3 楼 myairland 的回复:
个人认为,如果要在一个项目开始时引入一个JS框架来节省开发时间也好,增强页面效果也好,如果时间不是很充裕的话,我会选择用JQUERY,个人认为有以下几个好处 

1.没有牵扯大量面向对象理论,写出来的代码可以很过程式,易维护 
2.简单易学,一天就上手 
3.插件多 

然后EXT收费之后我对其除了鄙视还是鄙视 



呵呵,先共同鄙视以下EXT! 

JQUERY确实很好,设计思想很独到, 
JQUERY让我想…


竟然不能回帖了。。。。。 家里这几天的网速超慢,

刚工作的时候都是自己写js的,刚开始的时候那个痛苦,再加上闭包什么的,搞的头大。后来就开始用prototype感觉很好用

现在转到JQuery了,感觉JQuery更方便了。只是有的时候觉得这样傻瓜的框架会不会让自己变得堕落。所以有的时候还自己尝试着写一些js代码和闭包。

DOJO一直都没用过,这帖子得先收藏一下,呵呵。

#13


奔来看看。。。

#14


引用 12 楼 kokobox 的回复:
引用 11 楼 jinxfei 的回复:
引用 3 楼 myairland 的回复: 
个人认为,如果要在一个项目开始时引入一个JS框架来节省开发时间也好,增强页面效果也好,如果时间不是很充裕的话,我会选择用JQUERY,个人认为有以下几个好处 

1.没有牵扯大量面向对象理论,写出来的代码可以很过程式,易维护 
2.简单易学,一天就上手 
3.插件多 

然后EXT收费之后我对其除了鄙视还是鄙视 


呵呵,先共同鄙视以下EXT! 

JQUERY确实很好,设计…


你都收藏啦,感谢支持,呵呵。

#15


也鄙视一下收费的EXT。
ext是比较强大,但是有点大,还有就是有很多BUG

#16


学习了

#17


jquery比较好使,他的连缀,隐式迭代,大量的开源控件。。。不使用,不行啊。

#18


好文,我也收藏了

#19


收藏

#20


收藏,慢慢学习!

#21


楼主的文章是播种机

收藏了

#22


强烈支持!!!

#23


谢谢。。。。。。。。

#24


只用过JQuery 麻雀虽小,五脏俱全:用DOJO写一个最简单的控件

#25


ext 居然還收費﹐以前玩過一點點﹐鄙視它﹗
 
jquery 比較好﹗

頂﹗﹗

#26


项目正在用dojo,感觉这几个框架中,这个还是比较复杂的。jquery个人比较喜欢

#27


麻雀虽小,五脏俱全:用DOJO写一个最简单的控件还是自己写的好点!用一两年框架,连js 是什么都忘了

#28


dojo主要的优点体现在他的数据绑定,在js中实现了组件的mvc.
至于所说的jquery的过程式编程优点,dojo提供了dojo.query()方法予以支持.当初设计时不用$也是考虑到命名空间的问题.

#29


引用 15 楼 fejay 的回复:
也鄙视一下收费的EXT。 
ext是比较强大,但是有点大,还有就是有很多BUG


是啊,现在被那些BUG搞死了

#30


该回复于2009-07-01 21:37:17被版主删除

#31


该回复于2009-07-01 17:16:39被版主删除

#32


问一下楼主,怎么把java代码html,sql代码放入博客中,并格式化,我的意思就是说那些代码高亮在网页中的实现

#33


楼上的,不太清楚哦。

我只知道,CSDN的论坛有专门的代码标记,blog好像没有。

#34


JS控件,个人倾向于jquery,DOJO还没用过,学习了!

#35


暂时还没精力去学习,但是很感兴趣

#36


dojo的学习曲线是最大的,比MFC还费劲。。。

#37


z xuexi.

#38


引用 36 楼 healer_kx 的回复:
dojo的学习曲线是最大的,比MFC还费劲。。。


实际上还好,跟MFC比,那小巫见大巫了,只是DOJO文档不好,这一点让人头疼。

#39


用你最初版本的hello/world.js+helloworld.htm跑出来页面报错,错误信息为:_5 is null
[Break on this error] (35 out of range 16) dojo.js (第 35 行)
我用的是dojo-release-1.4.0rc2,请问如何解决?

#40


jquery 多好啊

#41


不会 明天看看

#42


LZ
 dojo.connect(this.typeIn,"onkeyup",this,"updateHello");//这行代码可能会引起 IE的内存泄漏
修改为
 this.connect(this.typeIn,"onkeyup",updateHello);//这个应该可以
_widget基类中定义了connect销毁的时候会把事件处理函数置为null解决内存泄漏

#43


"缺点:文档非常之差"
Can't agree more!

#44


开源与收费是两码事吧?