• 20、手把手教你Extjs5(二十)模块Grid的多列表方案


    对于有很多字段的模块在一个grid中显示所有的字段,会显得很臃肿,对于不同的用户其侧重的字段类型也不尽相同,因此就有必要为Grid的列表设计多个方案。在这个自定义系统进行设计的时候,我已经将这部分内容设计了进去,在ModuleModel.js中,在data下面有个属性tf_gridSchemes为数组型,你有多少种方案,都定义在这个下面就可以了,然后再创建一个控件可以根据这些定义来进行方案的选择,选择好以后让grid重新配置新的方案即可。

    先来看一下新增一个方案的配置信息,在ModuleModel.js中,修改tf_gridSchemes为以下内容:

    // 模块的grid方案,可以定义多个方案
    tf_gridSchemes: [{
        tf_schemeOrder: 10,
        tf_schemeName: 'Grid方案1', // 第一个grid方案
        // 表头分组
        tf_schemeGroups: [{
            tf_gridGroupId: 1, // id号
            tf_gridGroupOrder: 10, // 表头分组序号
            tf_gridGroupName: '工程项目基本信息',
            tf_isShowHeaderSpans: true, // 是否显示分组
            tf_isLocked: true, // 是否锁定此分组
            // 每一个表头分组下面的字段
            tf_groupFields: [{
                tf_gridFieldOrder: 5,
                tf_fieldId: 10100010
                // 工程id号
            }, {
                tf_gridFieldOrder: 10,
                tf_fieldId: 10100020, // 工程项目名称字段
                tf_columnWidth: 200
            }, {
                tf_gridFieldOrder: 20,
                tf_fieldId: 10100030, // 工程项目编码字段
                tf_columnWidth: 120
            }]
        }, {
            tf_gridGroupOrder: 20, // 表头分组序号
            tf_gridGroupName: '工程项目附加信息',
            tf_isShowHeaderSpans: false, // 是否显示headerspan
            tf_isLocked: false, // 是否锁定此分组
            tf_groupFields: [{
                tf_gridFieldOrder: 10,
                tf_fieldId: 10100040
            }, {
                tf_gridFieldOrder: 20,
                tf_fieldId: 10100050
            }, {
                tf_gridFieldOrder: 30,
                tf_fieldId: 10100060
            }, {
                tf_gridFieldOrder: 40,
                tf_fieldId: 10100070
            }, {
                tf_gridFieldOrder: 50,
                tf_fieldId: 10100080
            }, {
                tf_gridFieldOrder: 60,
                tf_fieldId: 10100090, // 是否通过验收
                tf_columnWidth: 80
            }, {
                tf_gridFieldOrder: 70,
                tf_fieldId: 10100100,
                tf_columnWidth: -1,  // -1表示这我可以撑足最大宽度
                tf_autoSizeDisabled: true // 不许自动适应宽度
                // 工程方量
            }]
        }]
    
    }, {
        tf_schemeOrder: 20,
        tf_schemeName: 'Grid方案2', // 第二个grid方案
        tf_schemeGroups: [{
            tf_gridGroupId: 1, // id号
            tf_gridGroupOrder: 10, // 表头分组序号
            tf_gridGroupName: '工程项目主要信息',
            tf_isShowHeaderSpans: false, // 是否显示分组
            tf_isLocked: false, // 是否锁定此分组
            tf_groupFields: [{
                tf_gridFieldOrder: 5,
                tf_fieldId: 10100010,
                tf_isLocked: true
            }, {
                tf_gridFieldOrder: 10,
                tf_fieldId: 10100020, // 工程项目名称字段
                tf_columnWidth: 200,
                tf_isLocked: true
            }, {
                tf_gridFieldOrder: 20,
                tf_fieldId: 10100030, // 工程项目编码字段
                tf_columnWidth: 120,
                tf_isLocked: true
    
            }, {
                tf_gridFieldOrder: 10,
                tf_fieldId: 10100040
            }, {
                tf_gridFieldOrder: 20,
                tf_fieldId: 10100050
            }]
        }]
    }, {
        tf_schemeOrder: 30,
        tf_schemeName: 'Grid方案3', // 第三个grid方案
        // 表头分组
        tf_schemeGroups: [{
            tf_gridGroupId: 1, // id号
            tf_gridGroupOrder: 10, // 表头分组序号
            tf_gridGroupName: '工程项目基本信息',
            tf_isShowHeaderSpans: true, // 是否显示分组
            tf_isLocked: true, // 是否锁定此分组
            tf_groupFields: [{
                tf_gridFieldOrder: 10,
                tf_fieldId: 10100020, // 工程项目名称字段
                tf_columnWidth: 200
            }, {
                tf_gridFieldOrder: 20,
                tf_fieldId: 10100030, // 工程项目编码字段
                tf_columnWidth: 120
            }]
        }, {
            tf_gridGroupOrder: 20, // 表头分组序号
            tf_gridGroupName: '工程项目附加信息',
            tf_isShowHeaderSpans: true, // 是否显示headerspan
            tf_isLocked: false, // 是否锁定此分组
            tf_groupFields: [{
                tf_gridFieldOrder: 10,
                tf_fieldId: 10100040
            }, {
                tf_gridFieldOrder: 20,
                tf_fieldId: 10100050
            }, {
                tf_gridFieldOrder: 30,
                tf_fieldId: 10100060
            }, {
                tf_gridFieldOrder: 40,
                tf_fieldId: 10100070
            }, {
                tf_gridFieldOrder: 50,
                tf_fieldId: 10100080
            }]
        }]
    
    }]

    在上面定义了三个gridScheme的方案,名称分别为“grid方案1”,“grid方案2”,“grid方案3”,每个方案下面又对字段分组,有些分组设置成了可以显示的二层表头,有些不显示多层表头,还设置了前面几列可以列锁定。数据有了,然后从Combo字段继承新建一个控件,用来可以选择这三个方案。在app/view/module下建立一个文件夹widget,将模块中用到的控件都放在这个下面。在widget目录中建立文件GridSchemeCombo.js。

    /**
     * 如果一个模块有多个Grid方案,那么在 pading上增加一个可以选择切换方案的Combo
     */
    
    Ext.define('app.view.module.widget.GridSchemeCombo', {
        extend: 'Ext.form.field.ComboBox',
        alias: 'widget.gridschemecombo',
        fieldLabel: '方案',
        editable: false,
        labelWidth: 40,
        labelAlign: 'right',
         200,
        queryMode: 'local',
        displayField: 'tf_schemeName', // data 中列表主案的名称
        valueField: 'tf_schemeOrder', // data 中列表主案的序号
        hidden: true, // 默认不显示,如果GridScheme的个数大于1则显示。
        bind: {
            hidden: '{gridSchemeHidden}', // 这是data中的一个计算字段,根据gridscheme个数来判断此控件是否显示
            value: '{gridSchemeId}' // 绑定gridSchemeId的值,在grid中,也绑定此值,这里改变以后,会去执行grid中的绑定事件
        },
        initComponent: function () {
            // 取得最顶层容器的viewModel,如果有更好的办法取得,请告知,谢谢
            var viewModel = this.up('modulepanel').getViewModel();
            this.store = Ext.create('Ext.data.Store', {
                fields: ['tf_schemeOrder', 'tf_schemeName'],
                data: viewModel.get('tf_gridSchemes')
            });
            this.value = viewModel.get('tf_gridSchemes')[0].tf_schemeOrder; // 默认的方案为第一个
            this.callParent(arguments);
        }
    });

    下面要在Grid的导航区域中加入此控件。先在uses中引入上面的控件,再修改bind,这样设置了bind 后,上面控件在选择了另一个方案以后,会来执行grid中的 setGridSchemeId这个函数,这个其实就是MVVM的本质。

    bind : {
            title : '{tf_title} {selectedNames}', // 数据绑定到ModuleModel中的tf_title和选中记录的名称
            gridSchemeId : '{gridSchemeId}' // 属性gridSchemeId
        // 设置绑定,和GridSchemeCombo是value绑定是一样的
    },

    下面加入改变了方案以后的执行函敉:

    setGridSchemeId : function(value) {
        if (this.gridSchemeId != value) {
            this.gridSchemeId = value;
            Ext.suspendLayouts();
            this.columns = app.view.module.factory.ColumnsFactory.getColumns(this
                            .up('modulepanel').getViewModel(), value);
            this.reconfigure(this.store, this.columns);
            Ext.resumeLayouts(true);
            this.columnAutoSize();
        }
    },

    在pagingtoolbar中加入此控件:

    // 创建grid列
    // 默认第一个grid方案
    this.gridSchemeId = viewModel.get('tf_gridSchemes')[0].tf_schemeOrder;
    // 将第一个方案的columns生成,第一个方案是要先设置好,并不是gridschemecombo触发来生成的
    this.columns = app.view.module.factory.ColumnsFactory.getColumns(viewModel);
    
    this.dockedItems = [{
        xtype: 'gridtoolbar', // 按钮toolbar
        dock: 'top',
        grid: this
    }, {
        xtype: 'pagingtoolbar', // grid数据分页
        store: this.store,
        displayInfo: true,
        prependButtons: true,
        dock: 'bottom',
        items: [{ // 在最前面加入grid方案的选择Combo
            xtype: 'gridschemecombo'
        }]
    }];

    ColumnsFactory.js的前面一部分也修改过了:

    /**
     * 用于生成Grid的Columns的类
     */
    
    Ext.define('app.view.module.factory.ColumnsFactory', {
    
        statics : {
            getColumns : function(moduleModel, schemeOrderId) {
                var scheme = moduleModel.get('tf_gridSchemes')[0]; // 取得第一个grid的方案
                if (schemeOrderId) { // 查找到相应的scheme
                    Ext.Array.each(moduleModel.get('tf_gridSchemes'), function(s) {
                        if (s.tf_schemeOrder == schemeOrderId) {
                            scheme = s;
                            return false;
                        }
                    })
                }
                var columns = [];

    为了加这个功能,改了许多处代码,又遇到了很多的bug,大家在切换方案的时候就会看到bug了。经过以上的操作,在模块打开的时候,可以看到在pagingtoolbar上多了一个控件,可以选择来改变grid的column方案了。这个改变方案的步骤也是应用MVVM的特性,上面的代码中没有看到事件的执行代码,因为事件在bind后是自动去执行的。

    下面贴一下加入此功能后的截图。

    1q3zobrc

    选择了第二个方案后

    tqtvdm4n

    选择了第三个方案后

    u4qxssoo

    对于一个管理系统来说,你的grid有以上几节所写的功能,系统的档次立马提高不少。但是在你没有理解的情况下不要盲目加入,要对系统的设计到功能的内部操作过程都了解了再加入相应功能。这套自定义的系统中完全没有重复的界面类,每一个类都是为了完成新的功能而建立的,到现在这节为止是手工建立了20多个类来协同工作,内部流程已经非常复杂了。等这个系统完全做好,前台会有200多个自定义类,后台也有几百个控制类,没有一定的编程功底和设计能力的话就很难掌控。再加上功能越深入,extjs的bug就会出现的越多,这真是一个头疼的问题。

    Grid的操作暂时告一段落,从下面会开始加入自定义Form、自定义图表的开发过程。

  • 相关阅读:
    [Luogu]小Z的AK计划
    [POI2006]OKR-Periods of Words
    [NOI2014]动物园
    [NOI2009]管道取珠
    [IOI2005]河流
    [国家集训队]Crash的文明世界
    [HDU5382]GCD?LCM!
    [AGC027E]ABBreviate
    [CF]Round510
    [NOIp2005]篝火晚会
  • 原文地址:https://www.cnblogs.com/niejunchan/p/4997012.html
Copyright © 2020-2023  润新知