1.2 Ext JS与AJAX
Ext JS采用XMLHttpRequest对象进行数据的异步交互,使用JavaScript增强用户体验,使用DOM组织内容,使用CSS显示外观,使用XML封装数据。Ext JS采用的技术如图1.9所示。
图1.9 Ext JS采用的技术
下面将对这几种技术进行简要的讲解,以使读者大体上了解这些技术。
1.2.1 XMLHttpRequest技术
从IE浏览器的5.0版本开始,微软公司通过一个名为XMLHTTP的ActiveX对象来实现在不刷新页面的情况下直接与服务器通信的能力,它的出现极大地丰富了浏览器/客户端模式的应用,因此其他浏览器(如Mozilla、Safari等)也实现了类似的对象。
但各个浏览器在实现XMLHttpRequest对象的方式上有很大的区别,比如在IE浏览器中XMLHttpRequest对象的实现方式如下:
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
而在其他的浏览器中,XMLHttpRequest对象的实现方式如下:
var xmlhttp = new XMLHttpRequest();
所以在创建一个XMLHttpRequest对象时,为了兼容不同的浏览器,开发人员一般采用如下写法:
var xmlhttp; if (window.XMLHttpRequest) {//判断是否采用new XMLHttpRequest()方式创建 xmlhttp = new XMLHttpRequest(); } else if (window.ActiveXObject) { try {//如果不是new XMLHttpRequest()对象方式创建,则是IE的方式创建 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { xmlhttp = new ActiveXObject('Msxml2.XMLHTTP'); } }
在Ext JS中,则采用如下方式创建XMLHttpRequest对象,示意代码如下所示:
var activeX = ['MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'], var http; try { http = new XMLHttpRequest();//默认采用new XMLHttpRequest()方式创建 } catch(e) { for (var i = 0; i < activeX.length; ++i) {//数组循环创建,创建成功则跳出循环 try { http = new ActiveXObject(activeX[i]); break; } catch(e) {} } }
在XMLHttpRequest对象创建完毕后,即可采用XMLHttpRequest来发送消息,发送消息有两种方式:一种是异步,另一种是同步。一般情况下,在AJAX中都使用异步方式来与服务器通信。通过XMLHttpRequest对象中open方法的第3个参数,可以用来设定是采用同步还是异步方式,参数为true代表异步,为false代表同步。设定通信的相关参数,即调用open方法,并不代表已经把信息发送给服务器了,只代表这个请求已经建立,要想把信息发送给服务器,还要调用send方法。
在采用异步方式通信时,还需要设定回调函数,以保证系统能够得到服务器端返回的代码,在设置回调函数的时候,一般都要增加两个状态来判断服务器是否处理成功,示例代码如下所示:
//设定回调函数 xmlhttp.onreadystatechange=function(){ if (4 == xmlhttp.readystate) {//表示服务器端数据已接受成功 if (200 == xmlhttp.status) {//表示请求成功,服务器端已经处理完成 //获取返回值 var txt = xmlhttp.responseText; var msg = document.getElementById("msg"); msg.innerHTML = txt; } } }
在Ext JS中,则采用如下方式来和服务器进行交互,示意代码如下所示:
function asyncRequest(method, uri, callback, postData) { var o = getConnectionObject() || null; //获取创建的XMLHttpRequest对象 if (o) { o.conn.open(method, uri, true); //设定文件头 if (pub.useDefaultXhrHeader) { initHeader('X-Requested-With', pub.defaultXhrHeader); } if(postData && pub.useDefaultHeader && (!pub.headers|| !pub.headers[CONTENTTYPE])){ initHeader(CONTENTTYPE, pub.defaultPostHeader); } //设定回调函数 handleReadyState(o, callback); //发送数据给服务器 o.conn.send(postData || null); } return o; } // 创建XMLHttpRequest对象 function getConnectionObject() { var o; //将创建的XMLHttpRequest对象进行计数 try { if (o = createXhrObject(pub.transactionId)) { pub.transactionId++; } } catch(e) { } finally { return o; } }
从上面的代码可以看到,Ext JS大体上也是按照XMLHttpRequest的基本原理来实现AJAX的。
1.2.2 JavaScript(Java脚本语言)
JavaScript是一种动态脚本语言,在真正的面向对象的语言中,例如“C++”或“Java”,有着用于定义“类”的关键字“class”,也有着“private”、“public”等关键字定义属性和方法的私有与公有。在JavaScript中,“类”的实现是直接通过函数实现的。在JavaScript中,使用“function”来构造类。比如:
function User(){ //用户类 this.name; //用户的姓名 this.sex; //用户的性别 }
函数“User”就定义了一个描述用户对象的类。然后可以用如下代码来创建对象:
var jack = new User();
在JavaScript的类构造函数中,通过“this”关键字向类中添加属性和方法。例如前面给出的“User”类中,使用“var this.name;”来声明一个属性。类中方法的添加与其类似,比如:
function User(){ //用户类 this.name; //用户的姓名 this.login = function(password){//用户的登录方法 //类的方法 alert(“我在执行登录操作,密码是:”+password); } }
继承是面向对象语言中扩展已有类型的一种有效途径,JavaScript没有提供用于实现继承的“extends”关键字或者“:”操作符,但是,作为一种动态语言,可以在需要的时候,用“prototype”向类中添加属性和方法。也就是说,JavaScript和一般真正的面向对象语言不同的是,JavaScript只能通过原型来实现模拟的继承,比如:
function ParentClass(){ //声明一个父类 this.data = "hutia"; //声明一个公共属性 } function SubClass(){ //声明一个子类 this.showSubData = function(){ //定义一个公共方法 alert("公共属性data的值是:"+this.data); } } SubClass.prototype = new ParentClass(); //使用原型来模拟继承 obj1 = new SubClass(); //创建一个子类的实例对象 obj1.showSubData(); //调用子类的公共方法
前面讲的是JavaScript如何实现面向对象的封装,Ext JS中extend(继承)方法的示例代码如下所示:
extend : function(){ //将o中的值放在作用域中 var io = function(o){ for(var m in o){ this[m] = o[m]; } }; var oc = Object.prototype.constructor; //返回函数 return function(sb, sp, overrides){ if(Ext.isObject(sp)){ overrides = sp; sp = sb; sb=overrides.constructor!=oc?overrides.constructor:function(){sp.apply(this, arguments);}; } var F = function(){}, sbp, spp = sp.prototype; //利用原型函数 F.prototype = spp; sbp = sb.prototype = new F(); sbp.constructor=sb; sb.superclass=spp; //利用构造函数 if(spp.constructor == oc){ spp.constructor=sp; } sb.override = function(o){ Ext.override(sb, o); }; sbp.superclass = sbp.supr = (function(){ return spp; }); sbp.override = io; Ext.override(sb, overrides); sb.extend = function(o){Ext.extend(sb, o);}; return sb; }; }(),
Ext JS中namespace(命名空间)方法的示例代码如下所示:
namespace : function(){ var o, d; Ext.each(arguments, function(v) { d = v.split("."); o = window[d[0]] = window[d[0]] || {}; Ext.each(d.slice(1), function(v2){ o = o[v2] = o[v2] || {}; }); }); return o; },
1.2.3 DOM(文档对象模型)
文档对象模型(DOM)是W3C组织的推荐标准,表示文档和访问、操作构成文档的各种元素的应用程序接口。在JavaScript中,用来获取ID标记元素的方法是:
document.getElementById()
为了方便使用,Ext JS对这个方法进行了封装,实现代码如下所示:
El.get = function(el){ var ex, elm, id; if(!el){ return null; } if (typeof el == "string") { //判断是否为字符串 if (!(elm = DOC.getElementById(el))) { return null; } if (ex = El.cache[el]) {//判断是否已经放在缓存中了,如果是,就直接取出DOM ex.dom = elm; } else {//如果没有放在缓存中,就放进去 ex = El.cache[el] = new El(elm); } return ex; } else if (el.tagName) { // 判断元素的tag名称 if(!(id = el.id)){ id = Ext.id(el); } if(ex = El.cache[id]){ ex.dom = el; }else{ ex = El.cache[id] = new El(el); } return ex; } else if (el instanceof El) { if(el != docEl){ el.dom = DOC.getElementById(el.id) || el.dom;//通过getElementById方法 El.cache[el.id] = el; // 进行缓存 } return el; } else if(el.isComposite) { return el; } else if(Ext.isArray(el)) { return El.select(el); } return null; }
从上面的代码可以看出,Ext JS提供的get方法,其实还是采用了document. getElementById()方法,只不过是对该方法进行了封装。
1.2.4 CSS(样式表)
CSS主要用于控制网页样式并可以将展现样式与网页内容分离。在HTML中有三种使用CSS的方式。
(1)采用<style type="text/css">标记,示例代码如下所示:
<html> <style type="text/css <!-- table {font: 12pt } --> </style> <body>
(2)直接在元素内使用CSS样式,示例代码如下所示:
<td style=" font: 12pt >字体大小为12</td>
(3)采用link把样式表引入网页,示例代码如下所示:
<head> <title>样式示例</title> <link rel=stylesheet href="../gf.css" type="text/css"> </head>
1.2.5 XML
扩展标记语言(XML)是一种简单的数据存储语言,使用一系列简单的标记描述数据,XML与Access、Oracle和SQL Server等数据库不同,数据库提供了更强有力的数据存储和分析能力,例如,数据索引、排序、查找、相关一致性等,XML仅仅是展示数据。XML是从1996年开始有其雏形,并向W3C(全球信息网联盟)提案,而在1998年2月发布为W3C的标准(XML1.0)。XML的前身是SGML(The Standard Generalized Markup Language),是IBM从20世纪60年代就开始发展的GML(Generalized Markup Language)标准化后的名称。一个典型的XML示例如下所示:
<?xml version="1.0" encoding="UTF-8"?> //引入文件 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"> <!—有关i18n的配置 --> <bean id="messageSource" class="org.springframework.context.support. ResourceBundleMessageSource" abstract="false" lazy-init="default" autowire="default" dependency-check="default"> <property name="basenames"> <list> <value>com.jl.ui.template.conf.i18n.template</value> <value>com.jl.framework.identity.idm.i18n. identityMessage</value> </list> </property> </bean> <!—其他的一些依赖bean --> <bean id="templateFacade" class="com.jl.ui.template.TemplateFacade"> <property name="template01Service" ref="template01Service" /> <property name="template02Service" ref="template02Service" /> <property name="template03Service" ref="template03Service" /> <property name="template04Service" ref="template04Service" /> <property name="template05Service" ref="template05Service" /> <property name="template06Service" ref="template06Service" /> <property name="template07Service" ref="template07Service" /> <property name="template08Service" ref="template08Service" /> <property name="template09Service" ref="template09Service" /> <property name="template10Service" ref="template10Service" /> </bean> </beans>
可以看到,XML主要是通过一些定义好的标记来表示所要存储的数据,这样程序就可以通过这些标记来读取内容。