一、开发一个“玩家信息”的功能~~ 效果图
【思路分析:】
这里需要一个grid组件去展示数据,grid组件需要一个columns数组显示返回结果,同时grid需要一个store,store需要一个model。同时grid也需要一个toolbar和queryForm。Grid表格是放在主视图里面的。这里一共就有8个组件。
我们约定好,除了store、main View是create,其他组件都采用define模式。个人习惯吧。
二、整理开发过程
需要组件推导过程如上,但是开发时反过来操作:
first:Model -- 提供模板,只需要改字段+类型,根据JAVA的实体。
seconde:Store -- 只需要修改url、跟model即可。若后台无完成,先写静态数据,让表格数据显示出来即可。
third: columns -- 因为显示的列比较多,这里把columns单独成一个数组来写。只需要修改表头。render对返回的值进行自定义输出。
four: toolbar – 几乎每一个功能都会附带一个查询框。这里先写好该queryForm组件。修改表单的name值跟字段名即可。
Five: grid – 修改columns+store名+toolbar名。将所有组件放到grid即可。
six: main view -- 主视图在onReady里面,加载grid主键即可。
Seven: function – 根据你的业务需求写 所有的事件函数
三、开发代码 ~~ 以下采用MVC分层的开发模式。
first:Model
/*-----------------------------1. model start-------------------------*/
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{ name : 'channel', type : 'string' },
{ name : 'channel_name', type : 'string' },
{ name: 'id',type:'long'},
{ name: 'createDate',type:'string'}
]
});
/*-----------------------------model end-------------------------*/
seconde:Store
/*-----------------------------2.store star-------------------------*/
var simpsonsStore = Ext.create('Ext.data.Store', {
model: 'User', //这里的Model直接引用上面定义的MODEL
pageSize: 1000,
storeId:'simpsonsStore',
remoteSort : true,
/* data : [
{channel: '管道一', channel_name: '腾讯', id: 1001, createDate: '2018-08-06 09:04:04'},
{channel: '管道二', channel_name: 'IOS', id: 1002, createDate: '2018-08-06 09:04:04'},
{channel: '管道三', channel_name: '百度', id: 1003, createDate: '2018-08-06 09:04:04'},
{channel: '管道四', channel_name: '测试管道', id: 1004, createDate: '2018-08-06 09:04:04'},
]*/
proxy: {
type: 'ajax',
actionMethods:'create',
extraParams: {},
url: project+'/game/UserInfo/roleDemo',
reader: {
type: 'json',
root: 'data',
totalProperty: 'count'
}
},
pageSize: 14,
autoLoad: true,
remoteSort: true,//全局排序
sorters: {
direction: 'ASC',
property: 'id'
}
});
/*-----------------------------store end-------------------------*/
third: columns
/*-----------------------------3.columns star-------------------------*/
var colunmArray=new Array(
{ text: '渠道', dataIndex: 'channel' },
{ text: '渠道名称', dataIndex: 'channel_name',renderer:function(value,meta,record){
return value+"("+record.data.channel+")";
}},
{ text: '渠道ID', dataIndex: 'id',
renderer : function(value){
if(value == 1001)
return '腾讯1001';
else if(value == 1002)
return 'ios1002';
else if(value == 1003)
return '百度1003';
else if(value == 1004)
return '测试渠道1004';
else
return 'PC';
}
},
{
text: '创建时间', dataIndex: 'createDate'
}
);
/*-----------------------------columns end-------------------------*/
four: toolbar
/*-----------------------------4.toolbar star-------------------------*/
/*
var xxxPanelForm1 = Ext.create('Ext.form.Panel',{
id:'xxxPanelForm',
layout: {
type:'hbox',
//控件横向拉伸,宽度为最控件的宽
/!*align:'stretchmax'*!/
},
border:'10 5 3 10',
bodyPadding: 5,
scrollable: false,
defaults: {
/!*labelWidth: 35,*!/
labelSeparator: ':'
},
items: [{
xtype: 'hidden',
fieldLabel: 'Id',
//allowBlank: false,
name:'pid'
},{
xtype: 'combobox',
fieldLabel: '等级1',
labelWidth:40,
matchFieldWidth:false,
name:'level',
width:150,
store: Ext.create('Ext.data.Store', {
fields: ['value', 'name'],
data : [
{"value":"HIGH", "name":"高"},
{"value":"MEDIUM", "name":"中"},
{"value":"LOW", "name":"低"}
]
}),
queryMode: 'local',
displayField: 'name',
valueField: 'value'
},{
xtype: 'textfield',
fieldLabel: '商品编号',
labelWidth:60,
margin:'0 0 0 10',
reference: 'productSearchForm-pnumber',
name:'pnumber',
//allowBlank : false,
},{
xtype: 'button',
margin:'0 0 0 10',
text: '查询',
}],
});
*/
Ext.define('Admin.view.myToolbar', {
extend:'Ext.toolbar.Toolbar',
id:"myfirstDefine",
xtype: 'myfirstDefine',
dock: 'top',
autoScroll:true,
items: [ {
xtype: 'combobox',
fieldLabel: '等级1',
labelWidth:40,
matchFieldWidth:false,
name:'level',
width:150,
store: Ext.create('Ext.data.Store', {
fields: ['value', 'name'],
data : [
{"value":"HIGH", "name":"高"},
{"value":"MEDIUM", "name":"中"},
{"value":"LOW", "name":"低"}
]
}),
queryMode: 'local',
displayField: 'name',
valueField: 'value'
},{
fieldLabel : '角色昵称',
labelWidth : 60,
xtype : 'textfield',
id : 'roleName',
name :'roleName',
// allowBlank : false, // 不能为空
emptyText : '昵称'
}, "-", {
fieldLabel : '手机号',
labelWidth : 60,
xtype : 'textfield',
id : 'phone',
name :'phone',
emptyText : '手机号'
}, "-", {
fieldLabel : '设备型号',
labelWidth : 60,
xtype : 'textfield',
id : 'deviceModel',
name :'deviceModel'
}, {
xtype : 'button',
text :'查询',
handler: function() {
fileSelect();
}
}]
});
/*-----------------------------toolbar end-------------------------*/
Five: grid
/*-----------------------------5.grid star-------------------------*/
Ext.define('Admin.view.product.ProductGrid', {
extend: 'Ext.grid.Panel',
xtype: 'productGrid',
viewConfig:{
enableTextSelection:true
},
id:'productGrid',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
//store:aaStore,
columns: colunmArray,
height: 400,
bbar : new Ext.PagingToolbar({
store : Ext.data.StoreManager.lookup('simpsonsStore'),
displayInfo : true,
displayMsg : '第 {0} - {1} 条 共 {2} 条 000',
emptyMsg : "没有记录"
}),
dockedItems: [
{xtype:"myfirstDefine"}
//xxxPanelForm1
]
});
/*var roleInfoGrid=Ext.create('Ext.grid.Panel', {
viewConfig:{
enableTextSelection:true
},
id:'gridPanel',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
//store:aaStore,
columns: colunmArray,
height: 400,
bbar : new Ext.PagingToolbar({
store : Ext.data.StoreManager.lookup('simpsonsStore'),
displayInfo : true,
displayMsg : '第 {0} - {1} 条 共 {2} 条 ',
emptyMsg : "没有记录"
}),
dockedItems: [
xxxPanelForm1,{xtype:"myfirstDefine"}
]
});*/
/*-----------------------------grid end-------------------------*/
six: main view
/*-----------------------------6.main view star-------------------------*/
Ext.onReady(function() {
var roleUrl=project+"/report/roleInfo.jsp";
var doUrl=project+"/report/speakForbidden.jsp";
Ext.create('Ext.container.Viewport', {
title:'角色帐号信息',
layout: {
type: 'fit'
},
items: [
//roleInfoGrid
{xtype:'productGrid'}
]
});
if(window.parent.stealPage){
Ext.getCmp("roleId").setValue(window.parent.tabRoleId);
window.parent.tabRoleId=null;
window.parent.stealPage=false;
fileSelect();
}
});
/*-----------------------------main view end-------------------------*/
Seven: function
Ext.define('Admin.view.product.ProductViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.productViewController',
productGridOpenAddWindow : function(){
//alert("添加商品的方法");
//alert("添加商品的方法");
var cfg = Ext.apply({
xtype: 'productGridWindow'
,items: [Ext.apply({xtype: 'productGridForm'})]
},{
title:'添加商品'//,width: 800//,height: 600
});
Ext.create(cfg);
},
productGridWindowClose:function(btn){
//alert("关闭");
var win = btn.up('window');
if(win){
win.close();
}
},
productGridFormSubmit:function(btn){
//alert("保存");
var productGridForm = btn.up('form').getForm();
var win = btn.up('window');
productGridForm.submit( {
//waitTitle : '请稍后...',
//waitMsg : '正在保存订单信息,请稍后...',
url : 'product/saveOrUpdate',
method : 'post',
success : function(form, action) {
Ext.Msg.alert("提示",action.result.msg);
win.close();
//必须SupplierGrid中增加对应id:'supplierGrid'属性
Ext.getCmp('productGrid').store.reload();
},
failure : function(form, action) {
Ext.Msg.alert("提示",action.result.msg);
}
});
},
productGridDeleteDate:function(btn){
//alert("11");
var grid = btn.up('gridpanel');
var selModel = grid.getSelectionModel();
if (selModel.hasSelection()) {
Ext.Msg.confirm("警告", "确定要删除吗?", function (button) {
if (button == "yes") {
var selected = selModel.getSelection();
var selectIds = []; //要删除的id
Ext.each(selected, function (record) {
//alert(record.data.pid);
selectIds.push(record.data.pid);
})
Ext.Ajax.request({
url : 'product/deleteByIds',
method : 'post',
params : {
ids:selectIds
},
success: function(response, options) {
Ext.getCmp('productGrid').store.reload();
var json = Ext.util.JSON.decode(response.responseText);
if(json.success){
Ext.Msg.alert('操作成功', json.msg);
grid.getStore().reload();
}else{
Ext.Msg.alert('操作失败', json.msg);
}
}
});
}
});
}else{
Ext.Msg.alert('提示',"请选择一行数据进行删除!");
}
},
productGridOpenEditWindow:function(btn){
//alert("xiugai");
var grid = btn.up('gridpanel');//获取Grid视图
var selModel = grid.getSelectionModel();//获取Grid的SelectionModel
if (selModel.hasSelection()) {//判断是否选中记录
var record = selModel.getSelection()[0];//获取选中的第一条记录.
//alert(record);
//console.log(record);
//创建修改window和form
var productGridWindow = Ext.widget('productGridWindow',{
title:'修改商品',
items: [{xtype: 'productGridForm'}]
});
//让form加载选中记录
productGridWindow.down("form").getForm().loadRecord(record);
}else{
Ext.Msg.alert('提示',"请选择一行数据进行修改!");
}
},
productSearchFormSubmit:function(btn){
//alert("你好");
var store = btn.up('gridpanel').getStore();
//2.按照所选字段进行查询参数(条件)的扩展
var formValues=btn.up('form').getForm().getValues();
//alert(formValues["pname"]);
//alert(formValues["pnumber"]);
//alert(formValues["level"]);
//alert(formValues["wname"]);
if (formValues["pname"]==''&&formValues["pnumber"]==''&&formValues["level"]=='' && formValues["wname"]=='') {
store.getProxy().extraParams ={ };
store.reload();
}else{
//alert("失败");
//1.清空所有查询条件
Ext.apply(store.proxy.extraParams, {
pname:'',
pnumber:'',
level:'',
wname:''
});
Ext.apply(store.proxy.extraParams, {
pname:this.lookupReference('productSearchForm-pname').getValue(),
pnumber:this.lookupReference('productSearchForm-pnumber').getValue(),
level:this.lookupReference('productSearchForm-level').getValue(),
wname:this.lookupReference('productSearchForm-wname').getValue()
});
store.load({params: {start:0,limit:14,page:1}});
}
},
productGridExportXls:function(){
//alert("商品导出");
window.location.href = "product/exportExcel";
}
});
基于上面的七大组件即可快速开发一个模块。而且写了自动生成model跟store的工具类,可以更快写出一个模块。
如果说,你理解好上面七个组件的使用关系的话,那么根据上面的理解,直接copy一份代码,直接改store、url即可
四、文件架构
这里,我把每个组件单独成一个文件,通过在主jsp中引入所有的组件的js即可互相使用。这种架构是MVC的。
可以看我的MVVC的文件架构 ~~ 第一个项目,拆分更细
虽然看着是很多的组件,如果说对这个框架熟悉的话,直接copy一份,然后把Product改成Order,这样就完成一个模块的开发。这个MVVM的代码会在下一篇博客去分享,有需要的可以一下。