1.1 Ext JS概述
Ext JS整合了XMLHttpRequest、JavaScript、DOM、CSS、XML等众多技术,它采用JavaScript编写,因为它与后台技术无关,所以开发人员可以直接使用Ext JS编写前台页面,无须建立任何应用服务器。
1.1.1 Ext JS的起源
Ext JS最初的目的是对Yahoo-UI进行扩展,由开发人员Jack Slocum开发,在开发过程中,他参考了Java Swing的实现机制,并深受《Head First Design Patterns》这本书的影响。如果读者查看Ext JS的源代码,就会发现各种模式的大量应用。Jack Slocum还对Ext JS的源代码进行了大量的封装,使得JavaScript具有了面向对象的特性。Ext JS的发展历史如图1.1所示。
图1.1 Ext JS的发展历史
Ext JS在设计之初就决定对跨浏览器进行支持,因此,开发人员在编写前台画面时,不需要考虑具体的浏览器。Ext JS支持的浏览器主要有:
● Windows Internet Explorer 6及更高版本
● Mozilla Firefox 1.5及更高版本
●Apple Safari 2及更高版本
● Opera 9及更高版本
前面讲过,Ext JS建立在Yahoo-UI基础之上,并深受Java Swing实现机制和设计模式的影响,Ext JS的构建图如图1.2所示。
图1.2 Ext JS的构建图
在Ext JS中,首先要判断客户端使用的是哪种浏览器,然后根据不同的浏览器提供相应的支持,比如在Ext JS提供的AJAX中,会使用循环来创建XMLHttpRequest对象,代码如下所示:
//判断客户端使用的浏览器 isOpera = check(/opera/), isChrome = check(/chrome/), isWebKit = check(/webkit/), isSafari = !isChrome && check(/safari/), isSafari3 = isSafari && check(/version\/3/), isSafari4 = isSafari && check(/version\/4/), isIE = !isOpera && check(/msie/), isIE7 = isIE && check(/msie 7/), isIE8 = isIE && check(/msie 8/), isGecko = !isWebKit && check(/gecko/), isGecko3 = isGecko && check(/rv:1\.9/), isBorderBox = isIE && !isStrict, isWindows = check(/windows|win32/), isMac = check(/macintosh|mac os x/), isAir = check(/adobeair/), isLinux = check(/linux/), isSecure = /^https/i.test(window.location.protocol); //存储创建XMLHttpRequest的active对象 var activeX = ['MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP']; function createXhrObject(transactionId) { var http; //首先通过new XMLHttpRequest()创建XMLHttpRequest,如果异常,则循环创建。 try { http = new XMLHttpRequest(); } catch(e) { for (var i = 0; i < activeX.length; ++i) { try { http = new ActiveXObject(activeX[i]); break; } catch(e) {} } } finally { return {conn : http, tId : transactionId}; } }
Ext JS除了使用自己的核心底层外,还可以使用其他常用的AJAX框架,比如YUI、Dojo、jQuery、Prototype等,如图1.3所示。
图1.3 Ext JS能够使用的核心底层
1.1.2 Ext JS的许可协议
在使用开源框架Ext JS之前,一定要了解框架基于哪种许可协议条款。Ext JS提供以下几个许可协议选项:
● 开放源码许可证:采用Open Source LGPL 3.0许可证的条款。如果打算在另一个开放源码项目或者个人、教育或非赢利项目中使用Ext JS,则要使用这个许可证。
● 商用许可证:如果希望在商业项目中使用Ext JS时避免开发源码许可证的某些限制,或者由于内部原因必须拥有许可证,或者希望在商业上支持Ext JS的开发,这是最合适的许可证。
● 原始设备生产商(OEM)/转售商许可证:如果打算对Ext JS进行重新打包,或者作为软件开发库销售Ext JS,这种许可证是最合适的。
1.1.3 Ext JS的应用示例
前面讲解了Ext JS的基础知识,读者可能会迫不及待地想体验一下Ext JS的效果,下面我们就通过一些示例来展示Ext JS美轮美奂的效果,先来看一下分页组件在Ext JS中的应用,如图1.4所示。
上述分页组件的源代码如下所示:
Ext.onReady(function(){ // 创建一个Store var store = new Ext.data.JsonStore({ root: 'topics', totalProperty: 'totalCount',
图1.4 分页组件在Ext JS中的应用
idProperty: 'threadid', remoteSort: true, //定义要加载的数据域 fields: [ 'title', 'forumtitle', 'forumid', 'author', {name: 'replycount', type: 'int'}, {name: 'lastpost', mapping: 'lastpost', type: 'date', dateFormat: 'timestamp'}, 'lastposter', 'excerpt' ], // 数据加载的方式和url proxy: new Ext.data.ScriptTagProxy({ url: 'http://extjs.com/forum/topics-browse-remote.php' }) }); store.setDefaultSort('lastpost', 'desc'); // 表示格式化要显示的内容 function renderTopic(value, p, record){ return String.format( '<b><a href="http://extjs.com/forum/showthread.php?t={2}"target="_blank">{0}</a></b><a href="http://extjs.com/forum/forumdisplay. php?f={3}" target="_blank">{1} Forum</a>', value, record.data.forumtitle, record.id, record.data.forumid); } function renderLast(value, p, r){ return String.format('{0}<br/>by{1}',value.dateFormat('M j,Y,g:i a'), r.data['lastposter']); } //创建一个表格组件 var grid = new Ext.grid.GridPanel({ el:'topic-grid', width:700, height:500, title:'ExtJS.com - Browse Forums', store: store, trackMouseOver:false, disableSelection:true, loadMask: true, //定义表格的栏位 columns:[{ id: 'topic', // id assigned so we can apply custom css (e.g. . x-grid-col-topic b { color:#333 }) header: "Topic", dataIndex: 'title', width: 420, renderer: renderTopic, sortable: true },{ header: "Author", dataIndex: 'author', width: 100, hidden: true, sortable: true },{ header: "Replies", dataIndex: 'replycount', width: 70, align: 'right', sortable: true },{ id: 'last', header: "Last Post", dataIndex: 'lastpost', width: 150, renderer: renderLast, sortable: true }], //分页需要用到的viewconfig viewConfig: { forceFit:true, enableRowBody:true, showPreview:true, getRowClass : function(record, rowIndex, p, store){ if(this.showPreview){ p.body = '<p>'+record.data.excerpt+'</p>'; return 'x-grid3-row-expanded'; } return 'x-grid3-row-collapsed'; } }, // 分页组件 bbar: new Ext.PagingToolbar({ pageSize: 25, store: store, displayInfo: true, displayMsg: 'Displaying topics {0} - {1} of {2}', emptyMsg: "No topics to display", items:[ '-', { pressed: true, enableToggle:true, text: 'Show Preview', cls: 'x-btn-text-icon details', toggleHandler: function(btn, pressed){ var view = grid.getView(); view.showPreview = pressed; view.refresh(); } }] }) }); // 渲染 grid.render(); // 加载分页数据,每页显示25笔 store.load({params:{start:0, limit:25}}); });
可以看到在Ext JS中要实现一个带分页组件的表格是一件很容易的事情,开发人员只需要指定数据源即可。除了表格之外,在Ext JS中创建表单元素也是非常方便的,比如创建一个在线编辑器,如图1.5所示。
图1.5 在线编辑器
上述在线编辑器的源代码如下所示:
var top = new Ext.FormPanel({ labelAlign: 'top', frame:true, title: 'Multi Column, Nested Layouts and Anchoring', bodyStyle:'padding:5px 5px 0', width: 600, //创建表单元素 items: [{ layout:'column', items:[{ columnWidth:.5, layout: 'form', items: [{ xtype:'textfield',//创建一个textfield fieldLabel: 'First Name', name: 'first', anchor:'95%' }, { xtype:'textfield', fieldLabel: 'Company', name: 'company', anchor:'95%' }] },{ columnWidth:.5, layout: 'form', items: [{ xtype:'textfield', fieldLabel: 'Last Name', name: 'last', anchor:'95%' },{ xtype:'textfield', fieldLabel: 'Email', name: 'email', vtype:'email', anchor:'95%' }] }] },{ xtype:'htmleditor',//创建一个在线编辑器组件 id:'bio', fieldLabel:'Biography', height:200, anchor:'98%' }], //定义该表单的按钮 buttons: [{ text: 'Save' },{ text: 'Cancel' }] }); //将该表单渲染到页面上 top.render(document.body);
除了常见的表格和表单组件外,Ext JS还提供了类似Google Map的组件,如图1.6所示。同时Ext JS还提供了编写图表的组件,如图1.7所示。
图1.6 类似Google Map的组件
图1.7 编写图表的组件
Ext JS还提供了各种各样的按钮组件,如图1.8所示。
上面简单地列举了一些常用的组件,通过上面各种示例的展示,读者可以看到,借助于Ext JS,开发人员可以很方便地实现原来需要大量代码才能实现的界面。
图1.8 各种各样的按钮组件