首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Dijit、ExtJS、jQuery UI 异同浅析(4)

Dijit、ExtJS、jQuery UI 异同浅析(4)

控件的架构实现在了解了 Dijit、ExtJS、jQuery UI 的使用方式之后,让我们从开发者的角度再来看看这些控件背后的架构与实现机制。
控件声明Dijit 篇:通过前面的使用范例可以看到 Dijit 控件是面向对象的。每个 Dijit 控件都是由 dojo.declare 方法声明的一个类。下面是 dijit.form.Button 控件的声明代码片段
清单 19. 声明 dijit.form.Button 类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
dojo.declare(
  // 控件名
  "dijit.form.Button",
  // 基类
  dijit.form._FormWidget, {
  // 成员属性
  baseClass: "dijitButton",
  templateString: dojo.cache("dijit.form", "templates/Button.html"),
  ...
  // 成员方法
  buildRendering: function(){...},
  reset: function(){...},
  _onClick: function(/*Event*/ e){...}
  ...
});




上述代码声明了一个 dijit.form.Button 类,在创建该控件对象时,只需通过 new 关键字进行实例化即可。
如果您了解 dojo.declare 用法(具体用法参见 )的话可以看出,控件类的声明方式与声明一个普通的 Dojo 类并没有什么区别。而一个 Dijit 控件类与普通 Dojo 类的主要区别在于 Dijit 控件类继承了一些特定的基类。在后文中将会为您介绍那些在背后支撑 Dijit 的基类。
ExtJS 篇: ExtJS 通过使用 Ext.extend 方法来实现继承,并声明一个新的控件类。以 Ext.Button 为例:
清单 20. 声明 Ext.Button 类
1
2
3
4
5
6
7
8
9
10
11
12
13
// 其中 Ext.BoxComponent 是一个继承自 Ext.Component 的类,
Ext.Button = Ext.extend(
  // 基类
  Ext.BoxComponent, {
  // 控件属性
  hidden: false,
  … .
  // 成员方法
  initComponent: function(){
     Ext.Button.superClass.iniiComponent.call(this);
     ...
  }
});




上述代码声明了一个基于 Ext.BoxComponent 的 Ext.Button 控件类。
在每一个控件类的声明结束后,还可以通过 Ext.reg 方法来为该控件类进行全局的注册,只有经过注册的控件类,才能通过描述符由之前提到的反射机制来生成:
清单 21. 注册 Ext.Button 类
1
Ext.reg('button',Ext.Button);




Ext.extend 方法除了提供继承的机制来声明新的控件,还能对已有的控件进行扩展,以 Ext.Component 为例:
清单 22. 扩展 Ext.Component 类
1
2
3
Ext.extend(Ext.Component, Ext.util.Observable, {
  // 新的成员变量以及方法
});




上述代码将 Ext.util.Observable 类的成员变量以及方法扩展到 Ext.Component 类中,并且将第三个参数对象中的成员变量及方法写入 Ext.Component 类中,这些属性及方法将覆盖 Ext.Component 类中的同名属性及方法。
jQuery UI 篇: jQuery UI 在 jquery.ui.widget.js 文件中提供了 $.widget 这个工厂方法来声明 jQuery UI 控件类。下面是 $.ui.button 控件的声明代码片段:
清单 23. 声明 $.ui.button 类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$.widget("ui.button", {
  options: {
     // 成员属性
     disabled: null,
     ...
  },
   
  // 声明体内只声明成员方法
  _create: function{
     ...
  },
  refresh: function{
     ...
  },
  ...
});




其书写方法与声明一个 Dijit/ExtJS 控件类较为类似,但需要注意的是,jQuery UI 控件的属性需要写在一个 options 对象中,而不是直接写在对象的声明体内。此外我们并没有像声明 Dijit/ExtJS 控件类那样为其指定一个父类,其原因将在下一节继承体系中说明。
既然 jQuery UI 控件的声明方法和 Dijit/ExtJS 控件如此类似,为什么它们的创建方法又如此不同呢?我们来看一下上面的代码片段背后到底做了哪些工作。
在调用 $.widget 方法时首先会声明一个名为 $.ui.button 类,理论上说,有了这个类,用户就可以通过 new 关键字来创建该控件类的实例了。
清单 24. 使用 new 方法创建 $.ui.button 控件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<html>
<head>
<script type="text/javascript">
  $(function){
     // 使用 new 关键字创建一个 label 为 button 的 $.ui.button 控件对象
     new $.ui.button({label: "button"}, $("#buttonNode"));
  });
</script>
</head>
<body>
  <div>
     <button id="buttonNode"></button>
  </div>
</body>
</html>




这样的书写方法和使用 Dijit 以及 ExtJS 的基本一致,但是为了保持和 jQuery 核心 API 一样的链式书写方式,在声明完这个控件类之后 ,$.widget 方法还会调用 $.widget.bridge 方法来向 $.fn(jQuery 对象的 prototype) 添加一个与控件名同名的插件方法,在本例中为 button。该方法在被调用时会根据传入的参数来决定是调用控件的方法,还是创建控件对象,或是取出已创建的控件对象来修改属性。
图 1. $.fn.button 方法运行流程图
返回列表