@king-
2015-05-17T11:24:51.000000Z
字数 7314
阅读 1318
web前端开发
Extjs中文文档:http://extjs-doc-cn.github.io/ext4api/
ExtJs导图:http://naotu.baidu.com/viewshare.html?shareId=avhhhfxdvwo4
个人积累分享:http://note.youdao.com/share/?id=5e9a1cf02ebdbd07466ff294127431a9&type=notebook
具体结构请查看:ExtJs导图

MDM3.0 web端界面结构使用MVC的拆分结构,不同的层应该放置在相应的文档目录下。
当有新功能页面产生的时候,我们将在根目录下创建属于该页面的相关同名html文件和js文件。同时在相应的controller文件目录下创建该页面的控制逻辑层文件,在view中创建相关的文件夹,并在该文件夹下存储该页面的视图代码。
(Ps:千万不要因为目录结构和文件类型不同而使得最外层页面文件、Controller文件、View中文件夹名称大小写都相同,不然你会后悔的)

app.html
<!-- 使用HTML5规范的文件头描述 --><!DOCTYPE html><html lang="zh-CN"><head><!-- 这里的两个meta写一个就可以--><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta charset="utf-8"><title>移动设备管理中心</title><script type="text/javascript" src="ext-4/ext-all-debug.js"></script><script type="text/javascript" src="ext-4/init.js"></script></head><body></body></html>
这里只需要引用ext-all-debug.js和init.js 就可以了
(延伸阅读:为什么 HTTP header 中 Content-Type 这一条目的写法是 charset 在 content 的属性里面?)
app.js
Ext.application({//引入相关组件类,和java的import导入类一个道理requires: ['Ext.container.Viewport', 'app.view.custom.BreadCrumb'],name: 'MDM',//定义命名空间appFolder: 'app',//描述相关文件所处的文件目录//定义控制 引入相关类controllers: ['app_Ctrl','Menu'],launch: function() {Ext.create('Ext.panel.Panel', {width: justsyConf.width,height: justsyConf.height,layout: 'border',//使用border形式布局items: [{region: 'north',//设置布局模块位置为northxtype: 'menubar',//使用组件split: false}, {region: 'north',xtype: 'breadcrumb',firstName: justsyLang.appstore,secondName: justsyLang.appmam}, {region: 'west',xtype: 'panel',width: 230,title: '<div class="head-title">' + justsyLang.appClassify + '</div>',layout: 'fit',//west布局下的panel组件使用fit布局方式items: [{xtype: 'apptree'//引入apptree这个组件}]}, {region: 'west',xtype: 'panel',cls: 'tran-cross',bodyCls: 'tran-cross',width: 6}, {region: 'center',xtype: 'panel',layout: 'border',items: [{region: 'north',height: 130,xtype: 'appstoresearch',title: '<div class="head-title">' + justsyLang.searchRules + '</div>',}, {region: 'north',xtype: 'panel',cls: 'tran-cross',bodyCls: 'tran-cross',height: 5}, {region: 'center',xtype: 'panel',layout: 'fit',items: [{xtype: 'applist',}]}, {region: 'south',xtype: 'appstoreoperate',height: 45}]}],renderTo: Ext.getBody() //将上面的内容渲染到html的body中})}});
appList_View.js
//这里的命名就是这个文件的包名,他的规则为【空间名.文件路径名称.文件名称】Ext.define("MDM.view.app.appList_View", {extend: 'Ext.grid.Panel', //组件继承的Extjs类//导入其他需要的Extjs组件类requires: ['Ext.data.*','Ext.grid.*','Ext.util.*','Ext.toolbar.Paging'],//alias 和 xtype 的作用是一样的,为了对现在创建的组件在外面使用而声明一个引用名alias: 'widget.devicereportlist',xtype: 'devicereportlist',//组件的唯一标识,可以通过Ext.getCmp(id)获取到组件id: 'devicereportlist',//组件使用的Store文件名store: 'DeviceOperate_Store',stripeRows: true,sortableColumns: true,viewConfig: {forceFit: true}, //自动分配列宽initComponent: function () {var store = this.store;var bbarId = this.bbarId;//创建列表首列的checkbox组件var sm = Ext.create('Ext.selection.CheckboxModel', {showHeaderCheckbox: false});Ext.apply(this, {selModel: sm,//将创建的checkbox赋予gird组件store: store,multiSelect: true,columns: [{text: justsyLang.deviceNo, //'设备号码',dataIndex: 'deviceNo',align: 'left',flex: 1,minWidth: 130}, {text: justsyLang.deviceName, //'设备名称',flex: 1,minWidth: 130,dataIndex: 'deviceName',renderer: this.isDeletedFn//使用renderer方法对数据显示前做预处理}],//bar 翻页组件配置bbar: {xtype: 'pagingtoolbar',id: bbarId,alias: 'widget.devicepagingtoolbar',pageSize: 25,store: store,displayInfo: true}});this.callParent();},isDeletedFn: function (value) {if (value == "Y") {return justsyLang.yes; //"是";} else if (value == "N") {return justsyLang.no; //"否";}}});
其他的 appOperate_View.js , appSearch_View.js这些view页面的编写都类似形式
app_Ctrl.js
Ext.define('MDM.controller.Dashboard', {extend: 'Ext.app.Controller',views: ['app.appList_View','app.appOperate_View','app.appSearch_View'],stores: ['appList_Store'],models: ['appList_Model'],init: function() {this.control({'appOperate button': {mouseover: this.showButtonInfo,mouseout: this.hideButtonInfo},'appSearch button[action=searchBtn]': {click: this.searchFn}}),}showButtonInfo: function(obj, e, eOpts) {CommFun.messBox([obj.id, obj.alertInfo], "button", "add")},hideButtonInfo: function(obj, e, eOpts) {CommFun.messBox([obj.id, obj.alertInfo], "button", "delete");},searchFn: function(btn) {var store = this.getappList_StoreStore();//获取搜索框中的相关参数var _form = btn.up('form').getForm().getValues(); //获取方法一var _form = Ext.getCmp('appSearchId').getForm().getValues(); //获取方法二/*** 和服务器发生数据交互的主要有两种方式,** 方法一: 使用 Store 和 Model 封装好的请求格式去直接请求和处理数据,* 这样的数据会自动处理数据和页面的对应关系,并渲染到页面上** 方法二: 使用传统的Ajax的思维,但是这样的数据ExtJs不会自动去识别View* 和View建立关系并自动渲染**///方法一 Store & Model//将参数交给代理请求方法(为代理请求的请求参数对象赋值)store.proxy.extraParams = _form;//发起请求 发起请求方法有多种store.load(); //方法一 直接load数据store.loadPage(1); //方法二 获取数据某一页store.reload(); //方法三 重新load数据//方法二 AjaxExt.Ajax.request({url: 'justsy/search/device',method: 'POST',loadingMask: true, //请求过程中是否需要有loading效果async: true, //设置Ajax请求类型为同步还是异步请求success: function(response) {var jsonObj = Ext.JSON.decode(response.responseText);if (jsonObj.success) {//手动获取组件并拿到组件下面的Store数据仓库,使用loadData的形式丢入相关的数据,这里数据应该是Array类型Ext.getCmp("appListId").getSotre().loadData(jsonObj.content);//同样是找到组件并获取到Store数据仓库,然后向其插入获取到的数据Ext.getCmp("appListId").getSotre().insert(jsonObj.conent);} else {//对错误进行相关的提示//这是ExtJs的写法Ext.MessageBox.alert("title", "errorMsg", callBack);//这是MDM3.0封装好的写法CommFun.messBox("title", "errorMsg", "callBack")}}})}});
Ext.define("MDM.view.app.appList_View", {extend: 'Ext.grid.Panel', //组件继承的Extjs类//导入其他需要的Extjs组件类requires: ['Ext.data.*','Ext.grid.*','Ext.util.*','Ext.toolbar.Paging'],//alias 和 xtype 的作用是一样的,为了对现在创建的组件在外面使用而声明一个引用名alias: 'widget.devicereportlist',xtype: 'devicereportlist',//组件的唯一标识,可以通过Ext.getCmp(id)获取到组件id: 'devicereportlist',//组件使用的Store文件名store: 'DeviceOperate_Store',stripeRows: true,sortableColumns: true,viewConfig: {forceFit: true}, //自动分配列宽listeners:{click:function(me, o){Ext.getMcp()}},initComponent: function () {var store = this.store;var bbarId = this.bbarId;//创建列表首列的checkbox组件var sm = Ext.create('Ext.selection.CheckboxModel', {showHeaderCheckbox: false});Ext.apply(this, {selModel: sm,//将创建的checkbox赋予gird组件store: store,multiSelect: true,columns: [{text: justsyLang.deviceNo, //'设备号码',dataIndex: 'deviceNo',align: 'left',flex: 1,minWidth: 130}, {text: justsyLang.deviceName, //'设备名称',flex: 1,minWidth: 130,dataIndex: 'deviceName',renderer: this.isDeletedFn//使用renderer方法对数据显示前做预处理}],//bar 翻页组件配置bbar: {xtype: 'pagingtoolbar',id: bbarId,alias: 'widget.devicepagingtoolbar',pageSize: 25,store: store,displayInfo: true}});this.callParent();},//===========================isDeletedFn: function (value) {if (value == "Y") {return justsyLang.yes; //"是";} else if (value == "N") {return justsyLang.no; //"否";}}//===========================});
里面包裹的部分就是一种对数据优化和预处理的方式之一。剩下的方式可以使用过滤器 filters 的方法去处理。
在过滤器 filters 中,我们可以在Store中写或者Model中写,应该依据不同情况去制定,但是在过滤器中修改后的数据,在record 原始数据 中的数据也就直接被修改了。
虽然web前端开发中对规范的遵循不是很严格,但是希望后续的开发中能严格起来,这样对自己代码的维护是很有帮助的。
只有定位了组件,你才可能对组件做一系列你想做的操作。
Ext.getCmp(id);//通过ID直接获取组件Ext.getCmp(id).getComponent(itemId);//通过itemId获取ID组件下的子组件Ext.getCmp(id).down('xtype/#Id');//通过xtype或者id获取ID组件下的子组件Ext.getCmp(id).up('xtype/#Id');//通过xtype或者id获取ID组件的上级组件Ext.get(id);//通过id获取组件的elementExt.StoreManager.lookup(StoreID);//通过StoreID获取到Store