面向Java开发者的Yahoo富UI组件库

YUI简介

基本上,YUI库是一个web应用各个方面相关组件的集合。主要分为一下几类:

◆组件/控件:

容器型组件(Container components),如面板,工具提示栏,对话框等。

UI控件(UI widgets),如按钮,日历,数据表格,下拉菜单,页码标注器,富文本编辑器等。

◆用于与服务器端交换信息的组件

◆用于控制DOM以及事件的组件

◆用于管理动画,拖曳,页面等的组件

每个组件的YUI源代码都有三种类型,在为你写的应用程序排错的时候很有助益。

◆标准型(Standard form):此类型用于理解组件的执行。

◆排错型(Debug enabled):开启此类型会显示排错信息。

◆压缩型(Compressed):此类型将代码中的空白清理掉,以提升下载速度。

JavaScript编程常见错误

JavaScript应用的开发与排错是相当繁琐的工作,尤其是对于Java开发者来说。错误不明显,即使用Firebug一类的JavaScript排错器也是一样。以下列出一些常见的JavaScript编程失误,以及其解决方法。

◆在定义变量的时候忘记使用关键词var定义本地变量,导致程序调用了函数外的变量。这种错误很难排除。

◆JavaScript中全都是函数,所以每次创建一个类的新实例时都必须使用关键字new。不然的话,JavaScript会调用该函数,并将结果赋值于等号左边的变量。

◆引用函数时不可在函数名称后使用圆括号,否则会变成调用函数。

◆输入DataTable组件的列宽,在IE和Firefox下显示不同。Firefox下比IE下要短20像素。

◆JavaScript在不同浏览器中行为不同。所以当你修改应用的时候要在不同的浏览器下测试效果。

◆如果你使用一个新的YUI组件,却忘记了include你的JavaScript源代码文件,你不会看到错误提示,但组件也无法工作。此问题可通过YUI加载器(YUI Loader)下载请求的源文件来解决,当然我更倾向于将组件与其所需求的源文件相联系。这样便可以精确的控制什么需要下载什么不要下载――和Java程序中import类的过程有点像。

YUI之OO(面向对象的)JavaScript设计

AJAX框架问世之前,JavaScript还算不上是一个应用开发平台。尽管它支持OO设计,JavaScript仅仅被当做一个脚本语言,用于实现有限的动态网页效果。为充分发挥JavaScript的OO设计,YUI在自己所有组件中都使用了OO设计。

以下部分举例说明了JavaScript中的OO编程方法,并介绍了构建OO JavaScript应用类的思路。YUI库提供的类十分有助于这种开发过程。

创建名字空间(Namespaces)

在企业软件中,将类按照名字空间下的行为来分类是非常普遍的做法。所以在学习创建类和对象之前,有必要了解名字空间。

如果你要把你所有的名字空间归到YAHOO名字空间之下,你在创建它们的时候可以这样写:

YAHOO.namespace("myapp");
YAHOO.namespace("myapp.util");
YAHOO.namespace("myapp.ui");

YAHOO.myapp.Main = function() {
}

以上代码创建了三个名字空间以及一个YAHOO.myapp名字空间下的类。

或者你也可以这样定义你自己的名字空间:

if(!DevX) DevX = {};
if(!DevX.myapp) DevX.myapp = {};

DevX.myapp.Main = function() {
}

管理文件

你可以在同一个JavaScript文件中定义多个类,但最好的做法是一个文件只定义一个类。

定义类

定义一个类有两种方法:建立一个实体对象(object literal),或定义一个函数。实体对象一般用于建立静态类,此类包含静态方法,无需通过构造器初始化便可使用。以下代码通过建立实体对象的方法定义了一个Util类。

假设util.js文件中有如下代码:

if(!DevX) DevX = {};
if(!DevX.myapp) DevX.myapp = {};

DevX.myapp.Util = {
TIMEOUT : 5, // Timeout constant in minutes for server requests
isBrowserIE : function() {
return YAHOO.env.ua.ie > 0;
}
}

使用这个类无需创建Util的实例。此类可以直接使用,方法如下:

if(DevX.myapp.Util.isBrowserIE()) {
// IE specific behavior
}

定义类的另一个方法,定义一个函数。假设main.js中有如下代码:

if(!DevX) DevX = {};
if(!DevX.myapp) DevX.myapp = {};

DevX.myapp.Main = function (title) { // 构造器
var t = title; // 私有变量
/**
* Private method
*/
function getTitle() {
return t;
}
/**
* Public method
*/
this.refresh = function () {
// 刷新主页
}
};

以下为创建实例和使用类的方法:

var main = new DevX.myapp.Main('Home page');
main.refresh();

当你往类中添加功能时,你的构造器也由于定义在其中的功能而越来越庞大。通过YAHOO.lang.augment这个方法可以在构造器之外定义方法和域。看看以下代码是如何往Main类中添加login功能的:

YAHOO.lang.augment(DevX.myapp.Main, {
login : function(username, password) {
//实现login功能的代码
}
});

实现类的继承

继承可以通过YAHOO.lang.extend方法来实现。考虑以下Main的继承类refresh方法是如何创建的:

main.js文件:

if(!DevX) DevX = {};
if(!DevX.myapp) DevX.myapp = {};

DevX.myapp.AppMain = function () {
//呼叫超级类构造器
DevX.myapp.AppMain.superclass.constructor.call(this, 'App Main');
//延伸类具体初始化
}

YAHOO.lang.extend(DevX.myapp.AppMain, DevX.myapp.Main);

DevX.myapp.AppMain.prototype.refresh = function () {
//修改refresh行为方法
}

关键词prototype(原型)指的是类的构造。

Web应用设计

至此,一个Java开发者对以上myapp的例子一定心存一些疑问。使用YUI就不用写HTML了吗?这个库和Java Swing API一样么?对于这两个问题,答案都是“否”。之前描述的应用使用HTML页面实现基本的UI元素。只是,每个页面现在都得到了JavaScript的支持,而且当需要时,这个JavaScript又可以使用YUI和其他的JavaScript库。YUI将被用来实现页面UI元素的事件处理(event handling),AJAX服务器交流,类似数据表格一类的UI元素,标注页码等等。

表格1提供了一些为web应用设计类时需要考虑的原则。假设你的应用有两个页面,每个页面都有一些UI元素,HTML和JavaScript类应当如同表格1中描述的方式工作。

表格1 你的应用中的HTML和JavaScript类

HTML 和 JavaScript 类 描述
/cxt/page1/Page1.htmlUI元素,版面
/cxt/page1/page1.csspage1的样式css
/cxt/page1/page1.jspage1的主类。组件初始化,注册事件,处理方法回调,与服务器交换信息
/cxt/page1/page1_util.jspage1的Utility方法
/cxt/page1/page1_datatable.js page1的数据表格实例浓缩
/cxt/page2/Page2.html?
/cxt/page2/page2.js?
/cxt/shared/js/util.js通用utility方法
/cxt/shared/js/myapp-datasource.js自定义的数据源
/cxt/shared/js/myapp-connection.js自定义的服务器连接类
/cxt/shared/css/myapp-table-skin.css数据表格的CSS

如果你的应用比这样的简单页面+富UI的模式更复杂,那么你设计类的时候还是考虑一些其他的策略吧。

结束语

通过以上文字,你应该了解了YUI能为你的应用做些什么,如何以OO设计的思路去开发网页和类,JavaScript的良好代码习惯,以及如何基于一个继承的类来创建符合自己需求的类。

相关推荐