快意编程:Ext JS Web开发技术详解
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

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 各种各样的按钮组件