@king-
2015-05-17T19:24:51.000000Z
字数 7314
阅读 1219
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',//设置布局模块位置为north
xtype: '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数据
//方法二 Ajax
Ext.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获取组件的element
Ext.StoreManager.lookup(StoreID);//通过StoreID获取到Store