Model
定义三个model
- /**
- * 对应Struts2中action的model
- */
- Ext.define('PriceAreaAction', {
- extend : 'Ext.data.Model',
- fields : [ 'priceArea', 'updatePriceEntrys', 'createPriceEntrys',
- 'deletePriceEntrys', 'message' ],
- proxy : {
- type : 'ajax',
- api : {
- create : 'savePriceArea.action',
- update : 'updatePriceArea.action'
- },
- writer : {
- type : 'json'
- },
- reader : {
- type : 'json'
- }
- }
- });
- /**
- * PriceArea的Model
- */
- Ext.define('priceAreaModel', {
- extend : 'Ext.data.Model',
- fields : [ 'id', 'areaCode', 'areaName', 'createUser', {
- name : 'createDate',
- type : 'number'
- }, 'modifyUser', {
- name : 'modifyDate',
- type : 'number'
- } ],
- hasMany : {
- model : 'entryModel',
- name : 'entryList',
- foreignKey : 'areaId',
- associationKey : 'entryList',
- primaryKey : 'id',
- storeConfig : Ext.data.StoreManager.lookup('entryStore')
- }
- });
- /*
- * PriceEntry的Model
- */
- Ext.define('entryModel', {
- extend : 'Ext.data.Model',
- fields : [ 'id', 'areaId', {
- name : 'price',
- type : 'number'
- }, 'priceType', 'createUser', {
- name : 'createDate',
- type : 'number'
- }, 'modifyUser', {
- name : 'modifyDate',
- type : 'number'
- } ],
- belongsTo : {
- type : 'belongsTo',
- model : 'priceAreaModel',
- primaryKey : 'id',
- foreignKey : 'areaId'
- }
- });
/** * 对应Struts2中action的model */Ext.define('PriceAreaAction', { extend : 'Ext.data.Model', fields : [ 'priceArea', 'updatePriceEntrys', 'createPriceEntrys', 'deletePriceEntrys', 'message' ], proxy : { type : 'ajax', api : { create : 'savePriceArea.action', update : 'updatePriceArea.action' }, writer : { type : 'json' }, reader : { type : 'json' } }}); /** * PriceArea的Model */Ext.define('priceAreaModel', { extend : 'Ext.data.Model', fields : [ 'id', 'areaCode', 'areaName', 'createUser', { name : 'createDate', type : 'number' }, 'modifyUser', { name : 'modifyDate', type : 'number' } ], hasMany : { model : 'entryModel', name : 'entryList', foreignKey : 'areaId', associationKey : 'entryList', primaryKey : 'id', storeConfig : Ext.data.StoreManager.lookup('entryStore') }});/* * PriceEntry的Model */Ext.define('entryModel', { extend : 'Ext.data.Model', fields : [ 'id', 'areaId', { name : 'price', type : 'number' }, 'priceType', 'createUser', { name : 'createDate', type : 'number' }, 'modifyUser', { name : 'modifyDate', type : 'number' } ], belongsTo : { type : 'belongsTo', model : 'priceAreaModel', primaryKey : 'id', foreignKey : 'areaId' }});
第一个model与服务器端的Action对应,后两个model与服务端的两个实体相似。在定义model的时候,也可以定义一对多的关系,在model中定义一个hasMany的属性,这个属性与服务端定义的List是一样的,它可以关联到另一个自定义的model,在这个hasMany中还要定义一个foreignKey,用于外键关联到另一个model对象上的上面的哪个属性。例子就是priceAreaModel关联到entryModel。
store
定义两个Store,priceAreaStore用于得到区域的信息,entryStore用于得到区域价格信息
- var priceAreaStore = Ext.create('Ext.data.Store', {
- pageSize : 20,
- model : 'priceAreaModel',
- autoLoad : true,
- proxy : {
- type : 'ajax',
- actionMethods : 'post',
- url : 'queryPriceArea.action',
- reader : {
- type : 'json',
- root : 'priceAreaList',
- totalProperty : 'totalCount'
- }
- }
- });
- var entryStore = Ext.create('Ext.data.Store', {
- model : 'entryModel',
- storeId : 'entryStore',
- proxy : {
- url : 'queryPriceEntryByPriceAreaId.action',
- type : 'ajax',
- reader : {
- type : 'json',
- root : 'priceEntryList'
- }
- }
- });
var priceAreaStore = Ext.create('Ext.data.Store', { pageSize : 20, model : 'priceAreaModel', autoLoad : true, proxy : { type : 'ajax', actionMethods : 'post', url : 'queryPriceArea.action', reader : { type : 'json', root : 'priceAreaList', totalProperty : 'totalCount' } }});var entryStore = Ext.create('Ext.data.Store', { model : 'entryModel', storeId : 'entryStore', proxy : { url : 'queryPriceEntryByPriceAreaId.action', type : 'ajax', reader : { type : 'json', root : 'priceEntryList' } }});
页面与操作
- Ext.require([ 'Ext.form.*', 'Ext.data.*', 'Ext.grid.Panel',
- 'Ext.layout.container.Column' ]);
- var priceAreaGrid = new Ext.grid.GridPanel({
- border : false,
- autoScroll : true,
- store : priceAreaStore,
- columns : [ {
- id : 'id',
- hidden : true,
- dataIndex : 'id'
- }, {
- text : i18n('page.module.oneToMany.areaCode'),
- name:'areaCode',
- flex : 1,
- sortable : true,
- dataIndex : 'areaCode'
- }, {
- text : i18n('page.module.oneToMany.areaName'),
- name:'areaName',
- flex : 1,
- sortable : true,
- dataIndex : 'areaName'
- }, {
- text : i18n('page.module.oneToMany.createUser'),
- name:'createUser',
- flex : 1,
- sortable : true,
- dataIndex : 'createUser'
- }, {
- text : i18n('page.module.oneToMany.createDate'),
- name:'createDate',
- flex : 1,
- sortable : true,
- renderer : changeToDate,
- dataIndex : 'createDate'
- }, {
- text : i18n('page.module.oneToMany.modifyUser'),
- name:'modifyUser',
- flex : 1,
- sortable : true,
- dataIndex : 'modifyUser'
- }, {
- text : i18n('page.module.oneToMany.modifyDate'),
- name:'modifyDate',
- flex : 1,
- sortable : true,
- renderer : changeToDate,
- dataIndex : 'modifyDate'
- } ],
- width : window.screen.clientWidth * 0.998,
- height : window.screen.availHeight * 0.7,
- frame : true,
- tbar : [ {
- text : i18n('page.module.oneToMany.add'),
- handler : function() {
- createWin(new priceAreaModel());
- }
- },{
- text : i18n('page.module.oneToMany.update'),
- handler : function() {
- var sm = priceAreaGrid.getSelectionModel();
- if (sm.getSelection().length > 0) {
- var record = sm.getSelection()[0];
- entryStore.load({
- params : {
- 'priceAreaId' : record.get("id")
- },
- callback: function(records, operation, success) {
- if(success){
- record.entryList().loadRecords(records,{});
- createWin(record);
- }
- }
- });
- } else {
- Ext.Msg.alert(i18n('page.module.oneToMany.message'), i18n('page.module.oneToMany.priceAreaGrid.message'));
- }
- }
- }, {
- text : i18n('page.module.oneToMany.delete'),
- handler : function() {
- var sm = priceAreaGrid.getSelectionModel();
- var selection = sm.getSelection();
- if (sm.getSelection().length > 0) {
- Ext.MessageBox.confirm(i18n('page.module.oneToMany.chick'),i18n('page.module.oneToMany.priceAreaGrid.chick_message'),
- function(btn) {
- if (btn == 'yes') {
- Ext.Ajax.request({
- url : 'deletePriceArea.action',
- params : {
- 'priceAreaId' : selection[0].data.id
- },
- success : function(
- response) {
- var json = Ext.decode(response.responseText);
- if (json.success == false) {
- Ext.MessageBox.alert(i18n('page.module.oneToMany.message'),json.message);
- } else {
- Ext.MessageBox.alert(i18n('page.module.oneToMany.message'),json.message);
- priceAreaStore.remove(selection);
- }
- },
- failure : function(response) {
- var json = Ext.decode(response.responseText);
- Ext.MessageBox.alert(i18n('page.module.oneToMany.message'),json.message);
- }
- });
- }
- });
- } else {
- Ext.Msg.alert(i18n('page.module.oneToMany.message'), i18n('page.module.oneToMany.priceAreaGrid.message'));
- }
- }
- } ],
- bbar : Ext.create('Ext.toolbar.Paging', {
- id : 'priceAreaGrid_pagingToolbar',
- store : priceAreaStore,
- displayMsg : i18n('page.module.oneToMany.priceAreaGrid.displayMsg'),
- displayInfo : true,
- items:[
- '-',{
- text: i18n('page.module.oneToMany.priceAreaGrid.page_count'),
- xtype: 'tbtext'
- },Ext.create('Ext.form.ComboBox', {
- width: 50,
- value: '20',
- triggerAction: 'all',
- forceSelection: true,
- editable: false,
- name: 'comboItem',
- displayField: 'value',
- valueField: 'value',
- queryMode: 'local',
- store : Ext.create('Ext.data.Store',{
- fields : ['value'],
- data : [
- { 'value':'10'},
- { 'value':'15'},
- { 'value':'20'},
- { 'value':'25'},
- { 'value':'40'},
- { 'value':'100'}
- ]
- }),
- listeners:{
- select : {scope : this,
- fn: function(_field,_value){
- var pageSize = priceAreaStore.pageSize;
- var newPageSize = parseInt(_field.value);
- if(pageSize!=newPageSize){
- priceAreaStore.pageSize = newPageSize;
- Ext.getCmp('priceAreaGrid_pagingToolbar').moveFirst();
- }
- }
- }
- }
- }),{
- text: i18n('page.module.oneToMany.priceAreaGrid.number'),
- xtype: 'tbtext'
- }]
- })
- });
- Ext.onReady(function() {
- setTimeout(function() {
- Ext.get('loading').remove();
- Ext.get('loading-mask').fadeOut({
- remove : true
- });
- }, 1000);
- Ext.QuickTips.init();
- Ext.form.Field.prototype.msgTarget = "side";
- Ext.create('Ext.Viewport',{
- layout : {
- type : 'border'
- },
- defaults : {
- split : true
- },
- width : window.screen.availWidth,
- height : window.screen.availHeight,
- items : [{
- xtype : 'form',
- id : "chack_form",
- region : 'north',
- border : false,
- hight : 50,
- width : 500,
- layout : {
- type : 'hbox',
- padding : 5
- },
- baseCls : 'x-plain',
- items : [{
- xtype : 'textfield',
- fieldLabel : i18n('page.module.oneToMany.areaCode'),
- labelPad : 2,
- labelWidth : 80,
- name : 'priceArea.areaCode',
- width : 250,
- hight : 25
- },{
- xtype : 'label',
- width : 50
- },{
- xtype : 'textfield',
- fieldLabel : i18n('page.module.oneToMany.areaName'),
- labelPad : 2,
- labelWidth : 80,
- name : 'priceArea.areaName',
- width : 250,
- hight : 25
- },{
- xtype : 'label',
- width : 50
- },{
- xtype : 'button',
- text : i18n('page.module.oneToMany.button_chick'),
- width : 100,
- hight : 25,
- handler : function() {
- priceAreaStore.load({
- params : {
- 'priceArea.areaName' : this.up('form').getForm().findField("priceArea.areaName").getValue(),
- 'priceArea.areaCode' : this.up('form').getForm().findField("priceArea.areaCode").getValue()
- }
- });
- }
- } ]
- }, {
- region : 'center',
- border:false,
- autoScroll : true,
- items : [ priceAreaGrid ]
- }]
- });
- });
Ext.require([ 'Ext.form.*', 'Ext.data.*', 'Ext.grid.Panel', 'Ext.layout.container.Column' ]); var priceAreaGrid = new Ext.grid.GridPanel({ border : false, autoScroll : true, store : priceAreaStore, columns : [ { id : 'id', hidden : true, dataIndex : 'id' }, { text : i18n('page.module.oneToMany.areaCode'), name:'areaCode', flex : 1, sortable : true, dataIndex : 'areaCode' }, { text : i18n('page.module.oneToMany.areaName'), name:'areaName', flex : 1, sortable : true, dataIndex : 'areaName' }, { text : i18n('page.module.oneToMany.createUser'), name:'createUser', flex : 1, sortable : true, dataIndex : 'createUser' }, { text : i18n('page.module.oneToMany.createDate'), name:'createDate', flex : 1, sortable : true, renderer : changeToDate, dataIndex : 'createDate' }, { text : i18n('page.module.oneToMany.modifyUser'), name:'modifyUser', flex : 1, sortable : true, dataIndex : 'modifyUser' }, { text : i18n('page.module.oneToMany.modifyDate'), name:'modifyDate', flex : 1, sortable : true, renderer : changeToDate, dataIndex : 'modifyDate' } ], width : window.screen.clientWidth * 0.998, height : window.screen.availHeight * 0.7, frame : true, tbar : [ { text : i18n('page.module.oneToMany.add'), handler : function() { createWin(new priceAreaModel()); } },{ text : i18n('page.module.oneToMany.update'), handler : function() { var sm = priceAreaGrid.getSelectionModel(); if (sm.getSelection().length > 0) { var record = sm.getSelection()[0]; entryStore.load({ params : { 'priceAreaId' : record.get("id") }, callback: function(records, operation, success) { if(success){ record.entryList().loadRecords(records,{}); createWin(record); } } }); } else { Ext.Msg.alert(i18n('page.module.oneToMany.message'), i18n('page.module.oneToMany.priceAreaGrid.message')); } } }, { text : i18n('page.module.oneToMany.delete'), handler : function() { var sm = priceAreaGrid.getSelectionModel(); var selection = sm.getSelection(); if (sm.getSelection().length > 0) { Ext.MessageBox.confirm(i18n('page.module.oneToMany.chick'),i18n('page.module.oneToMany.priceAreaGrid.chick_message'), function(btn) { if (btn == 'yes') { Ext.Ajax.request({ url : 'deletePriceArea.action', params : { 'priceAreaId' : selection[0].data.id }, success : function( response) { var json = Ext.decode(response.responseText); if (json.success == false) { Ext.MessageBox.alert(i18n('page.module.oneToMany.message'),json.message); } else { Ext.MessageBox.alert(i18n('page.module.oneToMany.message'),json.message); priceAreaStore.remove(selection); } }, failure : function(response) { var json = Ext.decode(response.responseText); Ext.MessageBox.alert(i18n('page.module.oneToMany.message'),json.message); } }); } }); } else { Ext.Msg.alert(i18n('page.module.oneToMany.message'), i18n('page.module.oneToMany.priceAreaGrid.message')); } } } ], bbar : Ext.create('Ext.toolbar.Paging', { id : 'priceAreaGrid_pagingToolbar', store : priceAreaStore, displayMsg : i18n('page.module.oneToMany.priceAreaGrid.displayMsg'), displayInfo : true, items:[ '-',{ text: i18n('page.module.oneToMany.priceAreaGrid.page_count'), xtype: 'tbtext' },Ext.create('Ext.form.ComboBox', { width: 50, value: '20', triggerAction: 'all', forceSelection: true, editable: false, name: 'comboItem', displayField: 'value', valueField: 'value', queryMode: 'local', store : Ext.create('Ext.data.Store',{ fields : ['value'], data : [ {'value':'10'}, {'value':'15'}, {'value':'20'}, {'value':'25'}, {'value':'40'}, {'value':'100'} ] }), listeners:{ select : {scope : this, fn: function(_field,_value){ var pageSize = priceAreaStore.pageSize; var newPageSize = parseInt(_field.value); if(pageSize!=newPageSize){ priceAreaStore.pageSize = newPageSize; Ext.getCmp('priceAreaGrid_pagingToolbar').moveFirst(); } } } } }),{ text: i18n('page.module.oneToMany.priceAreaGrid.number'), xtype: 'tbtext' }] })}); Ext.onReady(function() { setTimeout(function() { Ext.get('loading').remove(); Ext.get('loading-mask').fadeOut({ remove : true }); }, 1000); Ext.QuickTips.init(); Ext.form.Field.prototype.msgTarget = "side"; Ext.create('Ext.Viewport',{ layout : { type : 'border' }, defaults : { split : true }, width : window.screen.availWidth, height : window.screen.availHeight, items : [{ xtype : 'form', id : "chack_form", region : 'north', border : false, hight : 50, width : 500, layout : { type : 'hbox', padding : 5 }, baseCls : 'x-plain', items : [{ xtype : 'textfield', fieldLabel : i18n('page.module.oneToMany.areaCode'), labelPad : 2, labelWidth : 80, name : 'priceArea.areaCode', width : 250, hight : 25 },{ xtype : 'label', width : 50 },{ xtype : 'textfield', fieldLabel : i18n('page.module.oneToMany.areaName'), labelPad : 2, labelWidth : 80, name : 'priceArea.areaName', width : 250, hight : 25 },{ xtype : 'label', width : 50 },{ xtype : 'button', text : i18n('page.module.oneToMany.button_chick'), width : 100, hight : 25, handler : function() { priceAreaStore.load({ params : { 'priceArea.areaName' : this.up('form').getForm().findField("priceArea.areaName").getValue(), 'priceArea.areaCode' : this.up('form').getForm().findField("priceArea.areaCode").getValue() } }); } } ] }, { region : 'center', border:false, autoScroll : true, items : [ priceAreaGrid ] }] });});
打开的过程是:
- 点击新增(执行“createWin(new priceAreaModel());”,这里为什么要新建一个priceAreaModel,是为了让后面与form绑定的时候有一个对象)
- 得到价格区域编辑页面(根据传入的priceAreaModel对象绑定表单,执行priceForm.loadRecord(record);)
保存的过程是:
- 得到表单的绑定对象“new_record = form.getRecord();”;
- 在把表单的更新信息写入绑定对象“form.updateRecord(new_record);”);
- 新建设一个orderBillAction 对象var priceAreaAction = new PriceAreaAction();接下来要注意的下面这一点:priceAreaAction.phantom = new_record.phantom
一定要把得到的表单绑定信息的phantom这个属性值给action对象,这样才可以完成action对象的save方法的请求选择,如果phantom是true,那么就是执行“create”,否则就就执行“update”。
绑定对象中绑定的信息只能是表单中的信息,不能是表格中的信息,也就是priceAreaModel对象只能更新得到表单中的信息,不能得到表格中的订单明细信息,而且提交的信息是直接注入到Action中,所以要对订单明细信息做特别的处理。就是执行“processAction (_action,_record,_store)”方法,把增删改的订单明细信息加入到PriceAreaAction对象中,还有订单信息也注入到对象中。
- /**
- * 用于处理提交数据
- *
- * @param _action
- * @param _record
- * @param _store
- * @returns
- */
- function processAction(_action, _record, _store) {
- var _create = new Array();
- var _update = new Array();
- var _delete = new Array();
- var removed = _store.getRemovedRecords();
- var updated = _store.getUpdatedRecords();
- var newed = _store.getNewRecords();
- Ext.each(removed, function(record) {
- _delete.push(record.data);
- });
- Ext.each(updated, function(record) {
- _update.push(record.data);
- });
- Ext.each(newed, function(record) {
- _create.push(record.data);
- });
- _action.set('updatePriceEntrys', _update);
- _action.set('createPriceEntrys', _create);
- _action.set('deletePriceEntrys', _delete);
- _action.set('priceArea', _record.data);
- return _action;
- }
/** * 用于处理提交数据 * * @param _action * @param _record * @param _store * @returns */function processAction(_action, _record, _store) { var _create = new Array(); var _update = new Array(); var _delete = new Array(); var removed = _store.getRemovedRecords(); var updated = _store.getUpdatedRecords(); var newed = _store.getNewRecords(); Ext.each(removed, function(record) { _delete.push(record.data); }); Ext.each(updated, function(record) { _update.push(record.data); }); Ext.each(newed, function(record) { _create.push(record.data); }); _action.set('updatePriceEntrys', _update); _action.set('createPriceEntrys', _create); _action.set('deletePriceEntrys', _delete); _action.set('priceArea', _record.data); return _action;}
所以在PriceAreaAction这个model要定义增删改的区域价格明细信息属性与区域属性“'priceArea', 'updatePriceEntrys',
'createPriceEntrys','deletePriceEntrys'”,在方法中就要把增删改的信息分别set到PriceAreaAction对象中。
在model中定义一个proxy,信息如下:
- proxy : {
- type : 'ajax',
- api : {
- create : 'savePriceArea.action',
- update : 'updatePriceArea.action'
- },
- writer : {
- type : 'json'
- },
- reader : {
- type : 'json'
- }
- }
proxy : { type : 'ajax', api : { create : 'savePriceArea.action', update : 'updatePriceArea.action' }, writer : { type : 'json' }, reader : { type : 'json' } }
用PriceAreaAction对象的save方法,就会发一个create对应的URL(savePriceArea.action),用定义的writer把区域价格信息以JSON的格式写回到服务端。
修改过程说明:
- 双击表格中的行(执行“createWin(record);”,得到订单修改页面,根据传入的record对象绑定表单,执行“priceForm.loadRecord(record);”进行绑定);
- 进行表单信息与表格信息的修改;
- 点击保存,得到表单的绑定对象“new_record = form.getRecord();”;
- 在把表单的更新信息写入绑定对象“form.updateRecord(new_record);”);
- 接下来的过程与新增的一样。
在开发过程中可以要对日期进行处理,对日期做处理可以有如下正反向两种方式:
- /**
- * 修改date对象数据的JSON提交方式
- */
- Ext.JSON.encodeDate = function(d) {
- return d.getTime();
- };
- /**
- * 处理日期展现方式
- * @param value
- * @returns
- */
- function changeToDate(value) {
- if (value != null) {
- var date = new Date(value);
- return Ext.Date.format(date, 'Y-m-d H:i:s');
- } else {
- return null;
- }
- };
/** * 修改date对象数据的JSON提交方式 */Ext.JSON.encodeDate = function(d) { return d.getTime();};/** * 处理日期展现方式 * @param value * @returns */function changeToDate(value) { if (value != null) { var date = new Date(value); return Ext.Date.format(date, 'Y-m-d H:i:s'); } else { return null; }};