ExtJS主从表处理

 

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'
    }
});

 

第一个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'
        }
    }
});

 

 

页面与操作

 

 

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

 

 

通过以上方式就可以得到一个主页面,页面如下:



 页面中单击表格上方的新增按钮可以得到如下页面:



 打开的过程是:

 

  1. 点击新增(执行“createWin(new priceAreaModel());”,这里为什么要新建一个priceAreaModel,是为了让后面与form绑定的时候有一个对象)
  2. 得到价格区域编辑页面(根据传入的priceAreaModel对象绑定表单,执行priceForm.loadRecord(record);)

保存的过程是:

  1. 得到表单的绑定对象“new_record = form.getRecord();”;
  2. 在把表单的更新信息写入绑定对象“form.updateRecord(new_record);”);
  3. 新建设一个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;
}

 

所以在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'
        }
    }

 

用PriceAreaAction对象的save方法,就会发一个create对应的URL(savePriceArea.action),用定义的writer把区域价格信息以JSON的格式写回到服务端。

修改过程说明: 

  1. 双击表格中的行(执行“createWin(record);”,得到订单修改页面,根据传入的record对象绑定表单,执行“priceForm.loadRecord(record);”进行绑定);
  2. 进行表单信息与表格信息的修改;
  3. 点击保存,得到表单的绑定对象“new_record = form.getRecord();”;
  4. 在把表单的更新信息写入绑定对象“form.updateRecord(new_record);”);
  5. 接下来的过程与新增的一样。 

在开发过程中可以要对日期进行处理,对日期做处理可以有如下正反向两种方式:

/**
 * 修改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;
    }
};
 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值