天天看点

ExtJS4.0学习心得

学习ExtJs4.0知识已有一个月的时间,结合模拟项目——资源池管理系统,谈一谈学习中碰到的问题,解决办法以及收获的经验,希望可以达到互相交流、学习、共成长的目的。

ExtJs4.0不同于3.0版本的最重要改变是MVC模式的引入。本文也以MVC模式为切入点,开始介绍我的ExtJs4.0之旅。

一、SSH框架搭建后台

模拟项目采用了SSH搭建后台,数据库采用Oracle9i,前台可通过action将封装好的json数据进行读取等操作,具体构建细节此文不介绍,测试用数据如下表:

PID ID TEXT LEAF PIDS

1   基本信息 FALSE 0

2   人员信息 TRUE 1

3   日常工作 FALSE 0

......

22   Grid示例 TRUE 21

23   权限管理 TRUE 5

24   角色管理 TRUE 5

25 test 测试页面 TRUE 21

  Res.app.store.Tree数据

ID UNAME UPASSWORD XB XM AIH   ADDSDATAS

123  admin   admin  男 3    sfsf  2011-10-3

124  3    3   男 3 篮球, 足球 3  2011-10-6

Res.app.store.leaf.Test数据

二、建立文件结构

首先,按照API文档MVC模式介绍File Structure中的图示,建立模拟项目的文件结构,如图1所示。

ExtJS4.0学习心得

三、页面代码

完成index.jsp代码的编写,主要完成页面编码格式定义,ExtJs4.0样式、库文件引入,引入该页面需要加载的js文件。

<!--页面编码定义,考虑到中文输出,一般采用utf-8编码格式。 --> 

<%@ page language="java"pageEncoding="utf-8"%>

<!-- ExtJs4.0样式、类库导入。需要注意的是:ext-all.js(压缩后的Ext全部源码)和ext-all-debug.js(用于调试的无压缩Ext全部源码)只用导入一个即可。曾碰到在开发中若同时导入,在使用时出现异常的情况。--> 

<link rel="stylesheet"type="text/css"href="<%=basePath%>ext4/resources/css/ext-all.css" target="_blank" rel="external nofollow" >

<script type="text/javascript"src="<%=basePath%>ext4/ext-all.js"></script>

<!--引入该页面需要加载的js文件。--> 

<script type="text/javascript" src="app.js"></script>

四、Js部分代码

1.应用部分js代码(app.js)

该js代码段主要完成加载模式,命名空间,控制器的定义,组织起应用结构,通过Res.controller.Main控制器,利用别名将视图以“border”的布局方式渲染。

Ext.Loader.setConfig({enabled:true});//开启ExtJs4.0自动加载模式。

Ext.application({

name:'Res',//命名空间的名称,首字母大写,也可全部大写,不能与控制器重名。

appFolder:'app',//指定应用文件包名,与项目中一致,使用小写。

controllers:['Main'],//指定控制器,可以有多个,用’,’分隔,控制器名是controller目录下的js文件名。

    launch:function(){

       Ext.create('Ext.container.Viewport',{

           layout:'border',

           items:[

               {xtype:'header'},

               {xtype:'menutree'},

               {xtype:'south'},

               {xtype:'tabpanel'}

           ]

        });

    }

});

2.控制器部分js代码(Res.controller.Main)

控制器继承自Ext.app.Controller基类,它将需要的视图、数据、模型导入,通过方法调用完成数据、模型、视图之间的交互控制。

Ext.define('Res.controller.Main',{

extend:'Ext.app.Controller',

views: [    

  'menu.Tree',

       'menu.South',

       'menu.TabPanel',

       'menu.Header',

        'leaf.Test'

    ],

stores:[

  'Tree',

  'leaf.Test'

],

models:['Test'],

refs:[ 

       {ref:'menutree',selector:'treetab'},

       {ref:'tabpanel',selector:'treetab'}

    ], 

    init:function(){    

       this.control({           

         'menutree':{             

               itemmousedown: this.loadMenu

           } 

        }) 

    }, 

   loadMenu:function(selModel,record){     

        if(record.get('leaf')) { 

           var panel = Ext.getCmp(record.get('id')); 

           if(!panel){ 

               panel ={  

                   title:record.get('text'),                   

                   xtype:record.get('id'), 

                   closable: true 

               }               

               this.openTab(panel,record.get('id'));

           }else{

               var main = Ext.getCmp("content");

               main.setActiveTab(panel);  

           } 

       }  

    }, 

    openTab : function (panel,id){ 

        var o =(typeof panel == "string" ? panel : id || panel.id);

        var main =Ext.getCmp("content");

        var tab =main.getComponent(o);      

        if (tab) { 

           main.setActiveTab(tab);  

        } elseif(typeof panel!="string"){ 

           panel.id = o;  

           var p = main.add(panel); 

           main.setActiveTab(p);  

       }  

    } 

});

3.主页面js代码

视图部分要注意继承的基类一定是Ext的视图、组件,常用的有:Ext.Component、Ext.grid.Panel、Ext.tree.Panel、Ext.tab.Panel、Ext.window.Window等。视图如果定义了alias,可以经过控制器导入后,直接使用别名进行调用。调用时直接使用widget后面的字段。别名的部分也是ExtJs4.0的一个特色,为了便于理解可以这样去体会别名的机制:看作是通过代码自定义了一个视图,通过widget小控件包装起来,这样就可以让控制器识别并直接调用。当然Ext.require()、new等旧版本方法同样适用。

3.1.Res.view.Header(如图2)

Ext.define('Res.view.menu.Header', { 

    extend: 'Ext.Component', 

alias:'widget.header',

    initComponent: function() { 

       Ext.apply(this, { 

           xtype: 'box', 

           region: 'north', 

           html: '<h1>资源池管理系统</h1>', 

           height: 60 

        }); 

       this.callParent(arguments); 

    } 

});

ExtJS4.0学习心得

3.2.Res.view.South(如图3)

Ext.define('Res.view.menu.South',{ 

    extend: 'Ext.toolbar.Toolbar',

    alias:'widget.south',

    initComponent : function(){ 

       Ext.apply(this,{             

           frame:true, 

           region:"south", 

           height:23, 

           items:[

           "当前用户:Guest",

           '->',

           "技术支持:<ahref='http://www.chinasoft.com' target='_blank'style='text-decoration:none;'><font color='#0000FF'>http://www.chinasoft.com</font></a>  "] 

        }); 

       this.callParent(arguments); 

    } 

});

ExtJS4.0学习心得

3.3.Res.view.Tree(如图4)

Ext.define('Res.view.menu.Tree',{

extend:'Ext.tree.Panel',

alias:'widget.menutree',

initComponent:function(){

  Ext.apply(this,{ 

           title: '功能菜单', 

           margins : '1 1 1 1',

           region:'west', 

           border : false, 

           split: true, 

           width : 212, 

           minSize : 130, 

           maxSize : 300, 

           containerScroll : true, 

           collapsible : true, 

           autoScroll: false,

           useArrows:true,

   frame:true,

   store:'Tree'//在控制器中已导入,可直接通过文件名调用。

        }); 

  this.callParent(arguments);

}

});

ExtJS4.0学习心得

3.4.Res.view.TabPanel(如图5)

Ext.define('Res.view.menu.TabPanel',{ 

    extend: 'Ext.tab.Panel',

    alias:'widget.tabpanel',

    initComponent : function(){ 

       Ext.apply(this,{ 

           id:'content',

           region: 'center',

           margins : '1 1 1 1',

           defaults: { 

              autoScroll:true, 

              bodyPadding: 10 

           }, 

           activeTab: 0, 

           border: false, 

           plain: true, 

           items: [{ 

             title: '首页',

             layout: 'fit'

           }] 

        }); 

       this.callParent(arguments); 

    } 

});

ExtJS4.0学习心得

3.5.Res.view.leaf.Test(如图6)

Ext.define('Res.view.leaf.Test',{

extend:'Ext.grid.Panel',

alias:'widget.test',

store:'leaf.Test',

initComponent:function(){

  Ext.apply(this,{

   columnLines: true,

      bodyPadding:0,

     selModel:Ext.create('Ext.selection.CheckboxModel'),//加入选择框

   dockedItems:[{

            dock: 'bottom', 

            xtype: 'pagingtoolbar',//分页工具栏

            store: 'leaf.Test', 

            pageSize: 5, 

            displayInfo: true,

            displayMsg: '显示 {0} - {1} 条,共计 {2} 条',

            emptyMsg: '没有数据'

   }]//在grid底部显示分页信息

  });

  *****this.columns = [

   Ext.create('Ext.grid.RowNumberer'),

  {hidden:true,header:"id",dataIndex:"id"},

   {header:"用户名",sortable:true,dataIndex:"uname"},

   {header:"性别",dataIndex:"xb"},

   {header:"姓名",dataIndex:"xm"},

   {header:"爱好",dataIndex:"aih"},

  {name:"datas",xtype:'datecolumn',format:'Y-m-d',header:'出生日期',dataIndex:"datas"},

   {id:'adds',header:"住址",dataIndex:"adds"}

  ];//定义列信息、映射数据字段名、数据类型等。

  this.callParent(arguments);

}

});

ExtJS4.0学习心得

4.数据Store部分js代码

ExtJs4.0在数据的读取上做了比较大的修改,原有的异步Node、同步Node方式进行了封装,在4.0版本中有了新的proxy代理模块,减少了开发代码量,开发人员应注意检查数据路径的正确性,在读取封装好的json数据时,需要构造一个reader。

4.1.Res.store.Tree

Ext.define('Res.store.Tree',{

extend:'Ext.data.TreeStore',

autoload:true,

root:{

  text:'功能模块',

  expanded:true,

  id:'0-1'

},

proxy:{

  type:'ajax',

  [url='tree_getTree_Select.action]url:'tree_getTree_Select.action'[/url]

}

});

4.2.Res.store.leaf.Test

Ext.define('Res.store.leaf.Test',{

extend:'Ext.data.Store',

model:'Res.model.Test',

autoLoad:true,

proxy:{

  type:'ajax',

  [url='user_jsonSelect.action]url:'user_jsonSelect.action'[/url],

  actionMethods:'POST',

  reader:{

   type:'json',

   root:'result',

     totalProperty:'totalProperty',

   successProperty:'success'

  }

}

});

5.模型Model部分js代码(Res.model.Test)

模型层Model主要配合Store完成与后台实体类数据映射的名值配对,通过Store读取原始数据,在Model中形成与js代码相对应的fields数据。

Ext.define('Res.model.Test', {

extend : 'Ext.data.Model',

fields : [

  {name : "id"},

  {name : "uname"},

  {name : "xb"},

  {name : "xm"},

  {name : "aih"},

  {name : "datas",type:"date",mapping:'datas.time',dateFormat:"time"},

  {name : "adds"}

]

});

五、总结

ExtJS4.0学习心得

如图7所示,按照ExtJs4.0MVC模式,首先建立了文件结构,然后分别完成页面、应用层、视图层、数据层和模型层js代码的编写。页面加载应用层,应用层引入控制层和视图层,控制层通过各种方法完成视图、数据、模型层的交互控制,项目雏形已基本形成。

在项目进行过程中,遇到最多的问题是大小写、拼写异常,控制器引入异常,页面无显示且控制台无异常等。建议开发人员同时使用火狐(配合firebug)和IE浏览器,调试时,需要启用firebug网络功能,该功能可以反映出各种请求的响应情况,便于捕捉到产生问题的环节。控制台报错格式大多含义清晰,如碰到:g is null此类异常,请检查拼写。

本文只是学习ExtJs4.0的一个引子,还有很多未实现功能,项目进展到后期也有很多新问题,比如:js的不断增多会加重控制层负担,以至于影响加载速度;tabpanel中的不同tab会有重复代码,需要通过代码封装减少代码量;分页如何制作等等。希望有兴趣的朋友继续研究,多交流、讨论,由于个人技术所限,有很多不规范、可改进的地方,希望大家多提意见,共同进步。

不断地学习,每天让自己进步一点,从而站在不同的高度和角度,发现新的问题点,每一天都很新鲜,都很充实!

继续阅读