Ext Js 之坑

本专题作为开发笔记持续更新,记录遇到的各种坑以备查。

2010/5/16: 

Context: 以上一篇随笔中的Grid为例。例如,有两个Grid,一个是主类别,一个是子类型,分别定义在独立的另外两个文件中。另外有一个init.js用来组装这两个grid,可以这样:

代码
Ext.onReady(function() {
    
var RankDefGrid = new YC.RankDef.Grid();
    
var grid = new YC.Major.Grid();
    
//直接量在new完grid之后再赋值没有问题。
    grid.region = "west";
    grid.width 
= 300;
    
//尝试过直接修改store.url属性。但request的时候依然是原来的url。跟踪源码,发现应该如下设置。
    RankDefGrid.store.proxy.api["read"].url = "/RankDef/GetByRefEntityIdWithPaging";
    grid.sm 
= new Ext.grid.CheckboxSelectionModel({
        singleSelect : 
true,
        listeners : {
            
'rowselect' : function(sm, rowIndex, r) {
                
var id = sm.getSelected().get("Id");
                
if (RefConfigTab.getActiveTab().getId() == "Major_RankDef_ConfigPanel") {
                    RankDefGrid.store.removeAll();
                    RankDefGrid.store.baseParams[
"Id"= grid.getSelectionModel()
                            .getSelected().get(
"Id");
                    RankDefGrid.store.baseParams[
"refEntityName"= "Major";
                    RankDefGrid.store.load({
                        params : {
                            start : 
0,
                            limit : ALL_PAGESIZE_SETTING
                        }
                    });
                }
            },
            
'rowdeselect' : function(sm, rowIndex, r) {
                RankDefGrid.store.removeAll();
            }
        }
    });
    
//重设了sm。对应的,cm起始需要更改。所以把原来grid的initComponent方法中的原代码:
    //this.sm = new Ext.grid.CheckboxSelectionModel();改成:
    //this.sm = (this.sm) ? this.sm : new Ext.grid.CheckboxSelectionModel();并重新
    //调用initComponent方法。
    grid.initComponent();
    RankDefGrid.buildFormButtons 
= function() {
        
var btnSubmit = new Ext.ux.SubmitBtn({
            handler : 
function() {
                
var form = this.win.items.items[0];
                
if (form.getForm().isValid()) {
                    form.getForm().submit({
                        url : 
'/RankDef/SaveOrUpdate',
                        params : {
                            
'Id' : (form.updateEdit) ? form.entityId : "",
                            
'Major':grid.getSelectionModel().getSelected().get("Id")
                        },
                        success : 
function(form, action) {
                            RankDefGrid.store.setDefaultSort(
                                    
'Value''ASC');
                            RankDefGrid.store.load({
                                params : {
                                    start : 
0,
                                    limit : ALL_PAGESIZE_SETTING
                                }
                            });
                            RankDefGrid.win.destroy();
                        },
                        failure : 
function(form, action) {
                            JsHelper
                                    .ShowError(action.result.msg);
                        }
                    });
                }
            },
            
//scope 在这里没用...不知道为什么,所以把上面handler中的原来的"this"都改成了直接引用“RankDefGrid”
            scope: RankDefGrid
        });
        
var btnCancel = new Ext.ux.CancelBtn({
            handler : 
function() {
                
this.win.destroy();
            },
            scope : RankDefGrid
        });
        
return [btnSubmit, btnCancel];
    };
    
//应用sequence来添加赋值逻辑。
    Ext.sequence(RankDefGrid, 'showEditFormWinFn'function() {
        
var form = RankDefGrid.win.items.items[0];
        
var theMajor = form.form.findField("MajorText");
        theMajor.setValue(grid.getSelectionModel().getSelected().get(
"Name"));
    });

    
var RefConfigTab = new Ext.TabPanel({
        id : 
"Major_RefConfigTab",
        frame : 
true,
        border : 
true,
        region : 
"center",
        autoScroll : 
true,
        enableTabScroll : 
true,
        activeTab : 
0,
        items : [
new Ext.Panel({
            id : 
'Major_RankDef_ConfigPanel',
            title : 
'级别定义',
            autoScroll : 
true,
            layout : 
'fit',
            border : 
false,
            items : [RankDefGrid],
            listeners : {
                
'activate' : function(p) {
                    
if (grid.getSelectionModel().getSelected()) {
                        RankDefGrid.store.removeAll();
                        RankDefGrid.store.baseParams[
"Id"= grid.sm
                                .getSelected().get(
"Id");
                        RankDefGrid.store.baseParams[
"refEntityName"= "Major";
                        RankDefGrid.store.load({
                            params : {
                                start : 
0,
                                limit : ALL_PAGESIZE_SETTING
                            }
                        });
                    }
                    
//                    }
                }
            }
        })]
    });
    
var main = new Ext.Panel({
        border : 
false,
        layout : 
'border',
        items : [grid, RefConfigTab]
    });
    JsHelper.ExtTabDoLayout(main);
    grid.store.load({
        params : {
            start : 
0,
            limit : ALL_PAGESIZE_SETTING
        }
    });
});

对应的,应该对其他的grid做如下更改:

代码

Ext.ns(
'YC','YC.Major');

YC.Major.Grid 
= Ext.extend(Ext.grid.GridPanel, {
    enableColumnMove : 
true,
    stripeRows : 
true,
    frame : 
true,
    border: 
true,
    layout : 
"fit",
    loadMask : 
true,

    initComponent: 
function() {
        
this.viewConfig = {
            
// add view configuration here.
        };

        
this.store = this.buildStores()[0];

        
this.tbar = this.buildTopToolbar();
        
this.bbar = this.buildBottomToolbar();
        
//如果重设sm并再次执行initComponent方法,这样写就不会覆盖更改。        
        this.sm = (this.sm) ? this.sm : new Ext.grid.CheckboxSelectionModel();
        
this.cm = this.buildCm();
        
this.on("rowdblclick"this.onrowdblclick, this);
        YC.Major.Grid.superclass.initComponent.call(
this);
        
//如果这句放在上面基类方法调用之前,那么这句代码将无效:this.onSelectionChange方法不会被触发。
        this.getSelectionModel().on('selectionchange'this.onSelectionChange, this);
    },

    buildSM : 
function() {
        
return new Ext.grid.CheckboxSelectionModel();
    },

    
//Build Tool Bar
    buildTopToolbar : function() {
        
return [
            {
                xtype : 
"tbbutton",
                minWidth : 
80,
                ref : 
'../addBtn',
                text : 
"添加项",
                cls : 
"x-btn-text-icon",
                icon : 
"/Content/icons/add.png",
                handler : 
this.onAdd,
                scope: 
this
            },
            
"-",
            {
                xtype : 
"tbbutton",
                ref : 
'../delBtn',
                minWidth : 
80,
                disabled : 
true,
                text : 
"删除项",
                cls : 
"x-btn-text-icon",
                icon : 
"/Content/icons/delete.png",
                handler : 
this.onDelete,
                scope : 
this
            },
            
"-",
            {
                xtype : 
"tbbutton",
                minWidth : 
80,
                text : 
"双击修改项",
                cls : 
"x-btn-text-icon",
                icon : 
"/Content/icons/pencil.png",
                disabled : 
true
            }
        ];
    },
    buildBottomToolbar : 
function() {
        
return new Ext.PagingToolbar({
            displayInfo : 
true,
            emptyMsg : 
"没有数据显示",
            displayMsg : 
"显示从{0}条数据到{1}条数据,共{2}条数据",
            store : 
this.store,
            pageSize : ALL_PAGESIZE_SETTING,
            plugins : [
this.filters]
        });
    },
    
    
//CURD handlers
    onAdd : function(btn, e) {
        
this.showEditFormWinFn(this.store.reader, "添加专业");
    },
    onDelete : 
function(btn, e) {
        JsHelper.DelConfirm(
function(btn) {
            
if (btn == 'yes') {
                
// gridEditor.stopEditing();
                var s = this
                        .getSelectionModel()
                        .getSelections();
                
for (var i = 0, r; r = s[i]; i++) {
                    
this.store.remove(r);
                }
            }
        });
    },
    onrowdblclick : 
function(g, rowIndex, e) {
        
var store = g.getStore();
        
var id = store.getAt(rowIndex).get("Id");
        
this.showEditFormWinFn(this.store.reader, "修改专业", id);
    },
    onSelectionChange : 
function(sm) {
        
this.delBtn.setDisabled(sm.getCount() < 1);
    },    

    
//Grid Filters
    filters : new Ext.ux.grid.GridFilters({
        encode : 
true,
        filters : [{type: 
'string',dataIndex: 'Name'},
{type: 
'date',dataIndex: 'CreateTime'},
{type: 
'boolean',dataIndex: 'IsDelete'},
{type: 
'string',dataIndex: 'Id'}]
    }),
    
    
//Stores. Add additional stores in this function.
    buildStores : function() {
        
var store = new Ext.data.Store({
            url : 
"/Major/GetPlist",
            remoteSort : 
true,
            reader : 
new Ext.data.JsonReader({
                root : 
'data',
                totalProperty : 
'total',
                id : 
'Id'
            }, [
{name: 
'Name',type: 'string'},
{name: 
'CreateTime',type: 'date'},
{name: 
'IsDelete',type: 'boolean'},
{name: 
'Id',type: 'string'}
            ])
        });
        store.on(
'remove'this.onStoreRemove, this);
        store.setDefaultSort(
'Name''ASC');
        
return [store];
    },
    onStoreRemove : 
function(thiz, record, index) {
        Ext.Ajax.request({
            url : 
'/Major/Delete',
            params : {
                
'Id' : record.data.Id
            },
            success : 
function(response, opts) {
                
var result = Ext.util.JSON
                        .decode(response.responseText);
                
if (result.success == false) {
                    JsHelper.ShowError(result.msg);
                    
this.store.insert(0, record);
                }
            }
        });
    },    
    
    
//Build the popup win.
    //必须在new FormPanel的时候就设置formReader。如果new完了在用例如form.reader = formReader的方式将会无效,症状是值不会赋给datafield.
    buildWin : function(formReader) {
        
var form = new Ext.FormPanel({
            id : 
'mainForm',
            border : 
false,
            waitMsgTarget : 
true,
            labelWidth : 
90,
            frame : 
true,
            reader : formReader,
            bodyStyle : 
'padding:5px 5px 0',
            labelAlign : 
'right',
            layout : 
'tableform',
            layoutConfig : {
                columns : 
2
            },
            defaultType: 
'textfield',
            defaults: {
                allowBlank: 
false,
                 
150
            },
            items : [{name: 
'Name',xtype: 'textfield', fieldLabel : '专业名称'}],
            buttonAlign : 
'center',
            buttons : 
this.buildFormButtons()
        });
        
var win = new Ext.Window({
            iconCls : 
'application_form',
            width : 
700,
            resizable : 
false,
            constrain : 
true,
            autoHeight : 
true,
            modal : 
true,
            closeAction : 
'close',
            plain : 
true,
            items : [form]
        });
        
return win;
    },
    buildFormButtons : 
function() {
        
var btnSubmit = new Ext.ux.SubmitBtn({
            handler : 
function() {
                
var form = this.win.items.items[0];
                
if (form.getForm().isValid()) {
                    form.getForm().submit({
                        url : 
'/Major/SaveOrUpdate',
                        params : {
                            
'Id' : (form.updateEdit) ? form.entityId : ""
                        },
                        success : 
function(form, action) {
                            
this.store.setDefaultSort(
                                    
'Name''ASC');
                            
this.store.load({
                                params : {
                                    start : 
0,
                                    limit : ALL_PAGESIZE_SETTING
                                }
                            });
                            
this.win.destroy();
                        },
                        failure : 
function(form, action) {
                            JsHelper
                                    .ShowError(action.result.msg);
                        }
                    });
                }
            },
            scope: 
this
        });
        
var btnCancel = new Ext.ux.CancelBtn({
            handler : 
function() {
                
this.win.destroy();
            },
            scope : 
this
        });
        
return [btnSubmit, btnCancel];
    },
    showEditFormWinFn : 
function(formReader, title, id) {
        
this.win = this.buildWin(formReader);
        
var updateEdit = Ext.isDefined(id);
        
var formLoadArgs = (updateEdit) ? {
            url : 
'/Major/Get',
            params : {
                
'Id' : id
            },
            waitMsg : 
'数据加载中...'
        } : 
null;

        
var form = this.win.items.items[0];
        form.reader 
= formReader;
        form.updateEdit 
= updateEdit;
        form.entityId 
= id;
        
this.win.title = title;
        
this.win.show();
        
if (formLoadArgs) {
            form.load(formLoadArgs);
        }
    },    
    
    
//Build the grid ColumnModel
    buildCm : function() {
        
return new Ext.grid.ColumnModel([new Ext.grid.RowNumberer(), this.sm,
{header: 
'专业名称',dataIndex: 'Name',sortable: true},
{header: 
'创建时间',dataIndex: 'CreateTime',sortable: true}
        ]);
    }
});

Ext.reg(
"ycmajorgrid", YC.Major.Grid);

注意注释。 

原文地址:https://www.cnblogs.com/damnedmoon/p/1736519.html