使用Dijit实现界面组件化开发

对于组件化的软件工程设计,很多开发人员都比较熟悉。组件化的设计适合于复杂的软件系统和团队协作开发。把软件系统划分成若干个组件,组件之间通过预先定义好的接口和协议进行通讯和协作,共同完成整个软件系统的职责。团队中的开发人员可以各自负责不同的组件。组件化的思想在桌面应用和Web应用后台开发中比较流行,相关的技术和实践都比较成熟。而在Web应用的前端部分,组件化一直进展得比较缓慢。这其中的原因有很多,最主要的是Web应用的前端在开始的时候比较简单,没有组件化和设计的必要。随着Ajax应用的流行,Web前端部分越发复杂,用户对Web应用的要求不断向桌面应用靠拢。HTML语言的基本界面元素不能单独地满足这样的需求。菜单、树形控件、对话框和进度条等组件,在现在的Ajax应用中十分常见,但是并不是HTML默认提供的。HTML 5规范中引入了一些新的元素,但还是不够。组件化对于Web应用本身的代码共享和团队分工也是很有意义的。

\

Web 应用前端组件化的发展也是渐进的。开始的时候,只是一些简单的HTML、CSS加上JavaScript的代码示例。比如当需要实现一个多级菜单的时候,就下载相关的代码示例,就根据自己的需要进行修改。这样的组件比较难以复用。后来JavaScript框架开始流行的时候,有些框架本身就提供了组件的支持,包括Ext JS、jQuery UI和Dojo等。不过不同框架提供的组件模型不尽相同。

\

Dijit组件模型概述

\

Web 应用的前端组件的定义比较宽泛。一个组件占据Web页面上的某个区域,并负责完成某项具体的任务。Web组件有时候也被称为小部件(widget)。在 Dijit组件模型中,一个Dijit组件是一个JavaScript类,可以在页面上通过new操作符来创建组件的实例。每个组件实例都需要与页面上的某个DOM元素绑定在一起。这个DOM元素就是该组件的根节点。在Dijit组件的逻辑中,就可以对该根节点进行操纵来构建用户界面。组件 JavaScript类暴露出来的属性和方法就是该组件的接口。

\

Dijit组件的使用

\

Dijit 组件的使用方式非常简单。首先需要在页面上加载组件的JavaScript代码,这通过dojo.require函数就可以完成。接着在页面上找到或创建一个DOM元素作为该组件的根节点。最后通过new操作符创建即可。如new dijit.form.ComboBox({}, node)就可以用node作为根元素创建一个dijit.form.ComboBox组件,即一个下拉列表选择框。可以看到创建Dijit组件的时候,使用了两个参数:第二个参数是组件的根元素,如果创建的时候不指定该根元素,会自动创建一个新的DIV元素作为根元素。不过该新创建的根元素一般没有加入到当前的文档树中,可以通过组件的placeAt方法来设置该组件在页面文档树中的位置。第一个元素则是一个JavaScript对象,包含了组件的配置属性。通常来说,一个Dijit组件是可以复用的。因此一般都会提供一些属性供使用者进行配置。通过这个参数,就可以修改这些配置。

\

上面提到的是程序式的方式创建Dijit组件,还有另外的一种方式来进行创建,即通过在HTML代码中以声明式的方式创建,如

\
\\u0026lt;div dojoType=\"dijit.Dialog\" id=\"myDialog\" title=\"示例对话框\"\u0026gt;\    \u0026lt;h3\u0026gt;对话框标题\u0026lt;/h3\u0026gt;\    \u0026lt;div\u0026gt;对话框内容\u0026lt;/div\u0026gt;\\u0026lt;/div\u0026gt;
\

声明式的方式在一定程度上简化了开发人员使用Dijit组件的方式。声明式的方式与编写HTML代码的形式类似,只需要在一般的HTML元素上添加一些额外的属性就可以把HTML片段转换成Dijit组件。这对于只熟悉HTML语言的人来说非常方便,相当于在HTML语言的基本元素之上,增加了更多的可用组件。

\

Dijit深入分析

\

Dijit组件基本类

\

所有的Dijit组件都继承自dijit._Widget类。dijit._Widget类中定义了与组件相关的一系列方法。这些方法中有一些是与组件生命周期相关的,有一些则是所有组件都需要的通用方法。了解Dijit组件的生命周期有利于理解Dijit组件的运行方式,从而更好的使用已有的组件或开发出自己的组件。

\

创建Dijit组件的过程开始于dijit._Widget类中的create方法。create方法采用了典型的模板方法设计模式,即在该方法中封装了创建组件的基本流程。该方法会执行一些重要的操作,并依次调用其它的方法来完成整个创建过程。具体的流程包括:

\
  • 把创建时的配置参数混入(mix-in)到组件中。比如在创建组件的时候使用的方式是var myWidget = new TestWidget({prop : \"Hello\"}, node);,那么在创建完成之后就可以通过myWidget.prop来获取到\"Hello\",在组件中也可以通过this.prop来访问。\
  • 调用生命周期方法:postMixInProperties。该方法在配置参数混入之后调用,可以对混入的参数进行修改。\
  • 把该新创建出来的组件添加到全局的组件对象注册表中。Dijit组件都会被分配一个惟一的标识符。添加到注册表中之后,就可以用dijit.byId来根据标识符获取组件对象。\
  • 调用生命周期方法:buildRendering。该方法用来完成构建组件的用户界面。该方法负责设置this.domNode的值,表示的是创建完成的组件的根元素。\
  • 调用生命周期方法:postCreate。该方法在用户界面构建完成之后被调用。一般是组件内部行为逻辑的起点,类似HTML页面中的onload方法。\

对于Dijit组件开发人员来说,创建一个新的Dijit非常简单。只需要用dojo.declare声明一个JavaScript类并继承自 dijit._Widget,在该类中覆写感兴趣的JavaScript方法即可。最简单的情况是覆写postCreate方法并添加组件的逻辑。

\

对于用来包含其它子组件的容器类组件来说,一般会覆写startup方法来让其调用者显式的启动这个组件。这是因为在postCreate被调用的时候,只是保证了组件的DOM节点已经被创建成功了,但是这些DOM节点可能并没有被添加到当前文档树中,因此不能在postCreate中包含与DOM节点大小和位置相关的代码。如果要添加这样的代码,应该在startup中添加。很多容器类组件都使用该方法来对其子节点进行布局。

\

使用HTML模板

\

如果只是使用dijit._Widget的话,编写Dijit组件会比较繁琐。比如在构建用户界面的时候,可能会需要很多的DOM操作,编写起来也不方便。 Dijit提供了dijit._Templated用来使用HTML片段来定义组件的内容。HTML片段是作为组件的内容模板。如:

\
\dojo.declare(\"TempWidget\

你可能感兴趣的:(使用Dijit实现界面组件化开发)