• 13、手把手教你Extjs5(十三)模块字段和Grid列的定义[1]


    这一节加入模块自定义字段,并根据这些字段生成model。然后再定义grid中的分组和列。从这一切开始真正进入到了模块自定义的节奏当中,代码的复杂度和技巧性也大大提高。先从模块字段的自定义开始。先看一下ModuleModel.js中加入的新的定义:

    /**
     * 模块的数据模型
     */
    
    Ext.define('app.view.module.ModuleModel', {
        extend: 'Ext.app.ViewModel',
        alias: 'viewmodel.module',
    
        // 在开发过程中我先用设定好的值放于data中,等以后自定义的时候,data里的值都是从后台取得的
        // 所有数据库里的字段,我都以tf_开头,只是为了表示这是从后台读取过来的
    
        data: {
    
            tf_moduleId: '1010', // 模块ID号:一个数字的ID号,可以根据此ID号的顺序将相同分组的模块放在一块。
            tf_ModuleGroup: '工程管理',// 模块分组:模块分到哪个组里,比如说业务模块1、业务模块2、系统设置、系统管理等。
            tf_moduleName: 'Global', // 模块标识:系统中唯一的模块的标识
            tf_title: '工程项目',// 模块名称:能够描述此模块信息的名称。
            tf_glyph: 0xf0f7, // 图标字符值
            tf_shortname: null,// 模块简称:如果名称过长,有些地方可以用简称来代替。
            tf_englishName: null,// 模块英文名称:万一要制作英文版,可以用英文名称。
            tf_englishShortName: null, // 模块英文简称:可以用作生成编码字段。
            tf_description: null,// 模块描述:
            tf_remark: null,
            // 备注:
    
            // 下面还有若干字段未加入,以后用到的时候再加入
            tf_primaryKey: 'tf_id', // 主键
            tf_nameFields: 'tf_name', // 可用于描述记录的字段
    
            // 此模块的自定义字段,此处先用手工定义,以后换成从数据库中自动取得
            tf_fields: [{
                tf_fieldId: 10100010, // 此字段的id值,所有的字段都是保存在一字段表中,这是主键值
                tf_fieldName: 'tf_id',// 字段名
                tf_title: '序号',// 字段描述
                tf_fieldType: 'Integer', // 字段类型
                tf_isHidden: true, // 是否是隐藏字段
                tf_fieldGroup: '工程基本信息' // 字段分组
                // 是否是隐藏字段
            }, {
                tf_fieldId: 10100020,
                tf_fieldName: 'tf_name',
                tf_title: '工程项目名称',
                tf_fieldType: 'String',
                tf_fieldLen: 50,
                tf_isRequired: true, // 是否是必添项
                tf_fieldGroup: '工程基本信息'
    
            }, {
                tf_fieldId: 10100030,
                tf_fieldName: 'tf_code',
                tf_title: '工程项目编码',
                tf_fieldType: 'String',
                tf_fieldLen: 20,
                tf_isRequired: true,
                tf_fieldGroup: '工程基本信息' // 字段分组
    
            }, {
                tf_fieldId: 10100040, // 加入一个整型字段
                tf_fieldName: 'tf_squaremeter',
                tf_title: '建筑面积',
                tf_fieldType: 'Integer',
                tf_unitText: '平米', // 字段单位
                tf_fieldGroup: '工程附加信息',
                tf_allowSummary: true
                // 可以对此字段进行小计
            }, {
                tf_fieldId: 10100050, // 加入一个金额字段
                tf_fieldName: 'tf_budget',
                tf_title: '投资总额',
                tf_fieldType: 'Double',
                tf_isMoney: true, // 此字段是一个金额字段
                tf_fieldGroup: '工程附加信息',
                tf_allowSummary: true
            }, {
                tf_fieldId: 10100060, // 加入一个百分比字段
                tf_fieldName: 'tf_rjl',
                tf_title: '容积率',
                tf_fieldType: 'Percent',
                tf_fieldGroup: '工程附加信息'
            }, {
                tf_fieldId: 10100070, // 加入一个日期
                tf_fieldName: 'tf_startDate',
                tf_title: '计划开工时间',
                tf_fieldType: 'Date',
                tf_fieldGroup: '工程附加信息'
            }, {
                tf_fieldId: 10100080, // 加入一个日期
                tf_fieldName: 'tf_endDate',
                tf_title: '计划竣工时间',
                tf_fieldType: 'Date',
                tf_fieldGroup: '工程附加信息'
            }, {
                tf_fieldId: 10100090, // 加入一个布尔字段
                tf_fieldName: 'tf_isValid',
                tf_title: '是否通过验收',
                tf_fieldType: 'Boolean',
                tf_fieldGroup: '工程附加信息'
            }, {
                tf_fieldId: 10100100, // 加入一个数值字段
                tf_fieldName: 'tf_m3',
                tf_title: '工程方量',
                tf_fieldType: 'Double',
                tf_fieldGroup: '工程附加信息'
            }],
    
            // 模块的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: 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
                        // 计划竣工时间
                    }, {
                        tf_gridFieldOrder: 60,
                        tf_fieldId: 10100090, // 是否通过验收
                        tf_columnWidth: 80
                    }, {
                        tf_gridFieldOrder: 70,
                        tf_fieldId: 10100100
                        // 工程方量
                    }]
                }]
    
            }]
    
        },
    
        // 根据字段id,找到字段相应的定义
        getFieldDefine: function (fieldId) {
            var result = null;
            Ext.Array.each(this.data.tf_fields, function (field) {
                if (field.tf_fieldId == fieldId) {
                    result = field;
                    return false;
                }
            });
            return result;
        }
    
    })

    在上面代码中在data里面加入了tf_fields这个数组,这个数组下的每个元素都是一个字段,比如:

    {
        tf_fieldId : 10100020,
        tf_fieldName : 'tf_name',
        tf_title : '工程项目名称',
        tf_fieldType : 'String',
        tf_fieldLen : 50,
        tf_isRequired : true, // 是否是必添项
        tf_fieldGroup : '工程基本信息'
    
    }

    上面就定义了一个工程项目名称的字段,包括id号,字段名称,类型,长度,是否是必添项,分组信息等等。在这个工程项目模块中,我加入了各种类型的字段,有字符型,整型,浮点型,金额型,日期型,布尔型,都可以演示了看看效果。

    字段定义好了以后,需要能够根据字段的定义自动生成model。下面我编了一个model工厂的类,能根据ModuleModel中的定义自动生成一个model。先在module目录下面建立一个新的目录factory ,然后在这个下面建立一个文件 ModelFactory.js,内容如下:

    /**
     * 根据module的数据来生成模块的model
     */
    Ext.define('app.view.module.factory.ModelFactory', {
        // 静态变量或函数
        statics: {
            // 生成module的model,传入的数据是ModelModel中的data
            getModelByModule: function (moduleModel) {
                console.log('moduleModel');
                console.log(moduleModel);
                var module = moduleModel.data;
                return Ext.define('app.model.' + module.tf_moduleName, {
                    extend: 'Ext.data.Model',
                    module: module,
                    idProperty: module.tf_primaryKey, // 设置模块model的主键
                    nameFields: module.tf_nameFields, // 设置模块model的名称字段
                    fields: this.getFields(module), // 设置字段
    
                    // 取得主键值
                    getIdValue: function () {
                        return this.get(this.idProperty);
                    },
    
                    // 取得当前记录的名字字段
                    getNameValue: function () {
                        if (this.nameFields)
                            return this.get(this.nameFields);
                        else
                            return null;
                    }
                });
            },
    
            // 根据字段字义数组来生成model中的各个字段
            getFields: function (module) {
                var fields = [];
    
                for (var i in module.tf_fields) {
                    var fd = module.tf_fields[i];
                    var field = {
                        name: fd.tf_fieldName,
                        title: fd.tf_title,
                        type: this.getTypeByStr(fd.tf_fieldType)
                    };
                    if (field.type == 'string') {
                        field.useNull = true;
                        field.serialize = this.convertToNull;
                    }
                    if (field.type == 'date') {
                        field.dateWriteFormat = 'Y-m-d'; // 设置日期字段的读写格式
                        field.dateReadFormat = 'Y-m-d';
                    }
                    if (field.type == 'datetime')
                        field.dateReadFormat = 'Y-m-d H:i:s';
                    fields.push(field);
                }
                return fields;
            },
            // 将java中的数据类型转换成extjs5的字段类型
            getTypeByStr: function (str) {
                switch (str) {
                    case 'String':
                        return 'string';
                    case 'Boolean':
                        return 'boolean';
                    case 'Integer':
                        return 'int';
                    case 'Date':
                        return 'date';
                    case 'Datetime':
                        return 'date';
                    case 'Double':
                    case 'Float':
                    case 'Percent':
                        return 'float';
                    default:
                        return 'string';
                }
            },
    
            // 如果是空字符串,返回null
            convertToNull: function (v) {
                return v ? v : null;
            }
        }
    });

    上面是生成model的一个类。下面再继续看最上面的ModuleModel.js中data下的另一个属性:tf_gridSchemes,这个属性下的数据是用来定义grid的分组和列,tf_schemeGroups 是定义了若干个分组,tf_groupFields定义这些分组下面的具体的列。这些数据以后也都是保存在数据库中的,只要建立三张表,一张放方案名称,一张放分组名牌,一张放分组下面的字段定义。对表进行修改,就能把数据传给前台,重新展示就是新的一个grid的列方案。并且方案可以制订多个,在界面中方全的切换。

    下面的任务就是要为grid 生成columns,与上面生成model的方法相同,建立一个ColumnFactory.js程序,用来根据配置文件生成columns。

    /**
     * 用于生成Grid的Columns的类
     */
    
    Ext.define('app.view.module.factory.ColumnsFactory', {
    
        statics: {
            getColumns: function (moduleModel, schemeOrderId) {
    
                var scheme = moduleModel.get('tf_gridSchemes')[0]; // 取得第一个grid的方案
                var columns = [];
                for (var i in scheme.tf_schemeGroups) {
                    var sg = scheme.tf_schemeGroups[i];
                    // 是否需要显示分组
                    var isgroup = sg.tf_isShowHeaderSpans;
                    var group = {
                        gridGroupId: sg.tf_gridGroupId,
                        text: sg.tf_gridGroupName,
                        locked: sg.tf_isLocked,
                        //flex : 1,
                        columns: []
                    }
                    for (var j in sg.tf_groupFields) {
                        var gf = sg.tf_groupFields[j];
                        var fd = moduleModel.getFieldDefine(gf.tf_fieldId);
                        var field;
                        if (fd.tf_isHidden)
                            continue;
                        field = this.getColumn(gf, fd, moduleModel);
                        field.locked = sg.tf_isLocked;
                        if (isgroup) {
                            this.canReduceTitle(group, field);
                            group.columns.push(field);
                        } else
                            columns.push(field);
                    }
                    if (isgroup) {
                        this.canReduceTitle(group, field);
                        columns.push(group);
                    }
                }
                console.log(columns);
                return columns;
            },
    
            // 看看分组名称是不是 下面column 的开头,如果是开头的话,并且columntitle 后面有内容,就把
            // 相同的部分截掉
            canReduceTitle: function (group, field) {
                if (field.text.indexOf(group.text) == 0) {
                    field.text = field.text.slice(group.text.length).replace('(', '')
                            .replace(')', '').replace('(', '').replace(')', '');
                    if (field.text.indexOf("<br/>") == 0)
                        field.text = field.text.slice(5);
                }
            },
    
            /**
             * 根据groupField,fieldDefine的定义,生成一个column的定义
             */
            getColumn: function (gf, fd, module) {
    
                // console.log(fd);
                var ft = fd.tf_title.replace(new RegExp('--', 'gm'), '<br/>');
                if (fd.behindText)
                    ft += '<br/>(' + fd.behindText + ')';
    
                var field = {
                    filter: {},
                    maxWidth: 800,
                    gridFieldId: gf.tf_gridFieldId, // 加上这个属性,用于在列改变了宽度过后,传到后台
                    sortable: true,
                    text: ft,
                    dataIndex: fd.tf_fieldName
                }
    
                switch (fd.tf_fieldType) {
                    case 'Date':
                        Ext.apply(field, {
                            xtype: 'datecolumn',
                            align: 'center',
                             100
                        });
                        break;
    
                    case 'Datetime':
                        Ext.apply(field, {
                            xtype: 'datecolumn',
                            align: 'center',
                             130
                        });
                        break;
    
                    case 'Boolean':
                        field.xtype = 'checkcolumn';
                        field.stopSelection = false;
                        field.processEvent = function (type) {
                            if (type == 'click')
                                return false;
                        };
                        break;
                    case 'Integer':
                        Ext.apply(field, {
                            align: 'center',
                            xtype: 'numbercolumn',
                            tdCls: 'intcolor',
                            format: '#'
                        });
                        break;
                    case 'Double':
                        Ext.apply(field, {
                            align: 'center',
                            xtype: 'numbercolumn',
                             110
                        });
                        break;
                    case 'Float':
                        Ext.apply(field, {
                            align: 'center',
                            xtype: 'numbercolumn',
                             110
                        });
                        break;
                    case 'Percent':
                        Ext.apply(field, {
                            align: 'center',
                            xtype: 'numbercolumn',
                             110
                        })
                        break;
                    case 'String':
    
                        break;
                    default:
                        break;
                }
                if (fd.tf_allowSummary) {
                    Ext.apply(field, {
                        hasSummary: true,
                        summaryType: 'sum'
                    })
                }
    
                if (gf.tf_columnWidth > 0)
                    field.width = gf.tf_columnWidth;
                else if (gf.tf_columnWidth == -1) {
                    field.flex = 1;
                    field.minWidth = 120;
                }
                return field;
            },
    
            /**
             * 对于当前模块的name字段,加粗显示
             */
    
            nameFieldRenderer: function (val, rd, model, row, col, store, gridview) {
                return filterTextSetBk(store, '<strong>' + val + '</strong>');
            }
        }
    });

    文件的结构:

    n1fuvqg5

  • 相关阅读:
    Oracle 安装及其遇到的问题
    集合与Iterator
    Java 基本数据类型长度
    TextFile 类的创写
    Base64编码通过URL传值的问题
    HttpUrlConnection访问Servlet进行数据传输
    Servlet 的认识
    高聚合低耦合
    Exception loading sessions from persistent storage 这个问题的解决
    ARTS打卡计划第六周
  • 原文地址:https://www.cnblogs.com/niejunchan/p/4996947.html
Copyright © 2020-2023  润新知