ExtJS4.0学习心得

1 篇文章 0 订阅
1 篇文章 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所示。


三、页面代码
完成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">
<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文件名。
    /**创建底层视图,并通过别名将各部分视图以border布局方式渲染*/
    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',
/**引入视图,可以有多个,用','分隔,即view目录下的js文件路径。*/
views: [    
  'menu.Tree',
       'menu.South',
       'menu.TabPanel',
       'menu.Header',
        'leaf.Test'
    ],
/**引入数据,即store目录下的js文件路径。*/
stores:[
  'Tree',
  'leaf.Test'
],
/**引入模型,即model目录下的js文件路径。*/
models:['Test'],
/**创建关联关系,利用视图的别名关联到一个父对象*/
refs:[ 
       {ref:'menutree',selector:'treetab'},
       {ref:'tabpanel',selector:'treetab'}
    ], 
    /**进行初始化,创建menutree的鼠标点击方法*/
    init:function(){    
       this.control({           
         'menutree':{             
               itemmousedown: this.loadMenu
           } 
        }) 
    }, 
    /**该方法通过menutree数据获取leaf,判断panel是否存在,存在则打开,不存在则调用openTab方法*/
   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);  
           } 
       }  
    }, 
    /**该方法判断panel类型,在tabpanel中添加一个新的tab*/
    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',
/**创建north部分的标题视图*/
    initComponent: function() { 
       Ext.apply(this, { 
           xtype: 'box', 
           region: 'north', 
           html: '<h1>资源池管理系统</h1>', 
           height: 60 
        }); 
       this.callParent(arguments); 
    } 
});


3.2.Res.view.South(如图3)
Ext.define('Res.view.menu.South',{ 
    extend: 'Ext.toolbar.Toolbar',
    alias:'widget.south',
    /**创建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); 
    } 
});


3.3.Res.view.Tree(如图4)
Ext.define('Res.view.menu.Tree',{
extend:'Ext.tree.Panel',
alias:'widget.menutree',
/**创建west部分的菜单树视图*/
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);
}
});


3.4.Res.view.TabPanel(如图5)
Ext.define('Res.view.menu.TabPanel',{ 
    extend: 'Ext.tab.Panel',
    alias:'widget.tabpanel',
    /**创建center部分的表视图*/
    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); 
    } 
});


3.5.Res.view.leaf.Test(如图6)
Ext.define('Res.view.leaf.Test',{
extend:'Ext.grid.Panel',
alias:'widget.test',
store:'leaf.Test',
/**创建grid列表显示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);
}
});


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"}
]
});

五、总结


如图7所示,按照ExtJs4.0MVC模式,首先建立了文件结构,然后分别完成页面、应用层、视图层、数据层和模型层js代码的编写。页面加载应用层,应用层引入控制层和视图层,控制层通过各种方法完成视图、数据、模型层的交互控制,项目雏形已基本形成。
在项目进行过程中,遇到最多的问题是大小写、拼写异常,控制器引入异常,页面无显示且控制台无异常等。建议开发人员同时使用火狐(配合firebug)和IE浏览器,调试时,需要启用firebug网络功能,该功能可以反映出各种请求的响应情况,便于捕捉到产生问题的环节。控制台报错格式大多含义清晰,如碰到:g is null此类异常,请检查拼写。
本文只是学习ExtJs4.0的一个引子,还有很多未实现功能,项目进展到后期也有很多新问题,比如:js的不断增多会加重控制层负担,以至于影响加载速度;tabpanel中的不同tab会有重复代码,需要通过代码封装减少代码量;分页如何制作等等。希望有兴趣的朋友继续研究,多交流、讨论,由于个人技术所限,有很多不规范、可改进的地方,希望大家多提意见,共同进步。
不断地学习,每天让自己进步一点,从而站在不同的高度和角度,发现新的问题点,每一天都很新鲜,都很充实!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值