22、手把手教你Extjs5(二十二)模块Form的自定义的设计[1]

下面开始设计和完成一个简单的Form的自定义过程。先准备数据,在ModuleModel.js中的data属性下面,加入自定义Form的参数定义,下面的代码中定义了一个新的属性tf_formSchemes,在这个属性下面可以定义多个formScheme,下面的例子中只加入了一个,在formScheme上,加了二个fieldSet,然后在fieldSet下面定义了若干个字段。

// 模块的form方案,可以定义多个方案
tf_formSchemes: [{
    tf_schemeOrder: 10,
    tf_schemeName: 'form方案1', // 第一个form方案
    tf_windowWidth: 600, // form window 的宽度
    tf_windowHeight: -1, // 高度-1 即为自动适应高度
    // 表头分组
    tf_schemeGroups: [{
        tf_formGroupId: 1, // id号
        tf_formGroupOrder: 10, // 表头分组序号
        tf_formGroupName: '工程项目基本信息',
        tf_numCols: 1, // 分栏数
        // 每一个表头分组下面的字段
        tf_groupFields: [{
            tf_formFieldOrder: 5,
            tf_fieldId: 10100010,
            tf_colspan: 1, // 此字段占用的栏数
            tf_ -1,// 宽度,设置-1为 100%
            tf_isEndRow: true
            // 结束本行,下个字段从新的一行开始排列
        }, {
            tf_formFieldOrder: 10,
            tf_fieldId: 10100020, // 工程项目名称字段
            tf_colspan: 1, // 此字段占用的栏数
            tf_ -1,// 宽度,设置-1为 100%
            tf_isEndRow: true
            // 结束本行,下个字段从新的一行开始排列
        }, {
            tf_formFieldOrder: 20,
            tf_fieldId: 10100030, // 工程项目编码字段
            tf_colspan: 1, // 此字段占用的栏数
            tf_ -1,// 宽度,设置-1为 100%
            tf_isEndRow: true
            // 结束本行,下个字段从新的一行开始排列
        }]
    }, {
        tf_formGroupOrder: 20, // 表头分组序号
        tf_formGroupName: '工程项目附加信息',
        tf_numCols: 2, // 分栏数
        tf_collapsible: true, // 此fieldSet可折叠
        tf_collapsed: false, // 默认不折叠
        // 每一个表头分组下面的字段
        tf_groupFields: [{
            tf_formFieldOrder: 10,
            tf_fieldId: 10100040
            // 建筑面积
        }, {
            tf_formFieldOrder: 20,
            tf_fieldId: 10100050
            // 投资总额
        }, {
            tf_formFieldOrder: 30,
            tf_fieldId: 10100060,
            tf_isEndRow: true
            // 结束本行,下个字段从新的一行开始排列
            // 容积率
        }, {
            tf_formFieldOrder: 40,
            tf_fieldId: 10100070
            // 计划开工时间
        }, {
            tf_formFieldOrder: 50,
            tf_fieldId: 10100080
            // 计划竣工时间
        }, {
            tf_formFieldOrder: 60,
            tf_fieldId: 10100090
            // 是否通过验收
        }, {
            tf_formFieldOrder: 70,
            tf_fieldId: 10100100
            // 工程方量
        }]
    }]

}]

基础数据准备就绪,就需要创建window了。在module目录下创建一个新的目录window,在 window目录下建立文件BaseWindow.js。

/**
 * 
 * 一个显示、修改、新增的的窗口基类
 * 
 */
Ext.define('app.view.module.window.BaseWindow', {
    extend: 'Ext.window.Window',
    alias: 'widget.basewindow',

    uses: ['app.view.module.form.BaseForm'],

    layout: 'fit',
    maximizable: true,
    closeAction: 'hide',

    bodyStyle: 'padding : 2px 2px 0',
    shadowOffset: 30,
    layout: 'fit',

    initComponent: function () {
        this.maxHeight = document.body.clientHeight * 0.98;

        var me = this;

        this.formScheme = this.getViewModel().get('tf_formSchemes')[0]; // 取得第一个form方案
        console.log(this.formScheme);
        this.title = this.getViewModel().get('tf_title');
        this.glyph = this.getViewModel().get('tf_glyph');

        var w = this.formScheme.tf_windowWidth;
        var h = this.formScheme.tf_windowHeight;
        // 高度为-1表示是自适应
        if (w == -1 && h == -1) {
            this.width = 600;
            this.height = 400;
            this.maximized = true;
        } else {
            if (w != -1)
                this.width = Math.min(w, document.body.clientWidth - 2);
            if (h != -1)
                this.height = Math.min(h, document.body.clientHeight - 2);
        };
        if (w == -1 && h != -1) { // 宽度最大化
            this.width = document.body.clientWidth - 40;
        }
        this.tools = [{
            type: 'collapse',
            tooltip: '当前记录导出至Excel'
        }];

        this.items = [{
            xtype: 'baseform',
            viewModel: this.getViewModel(),
            formScheme: this.formScheme
        }]
        this.callParent(arguments);
    }

});

在这个window中根据,配置信息来创建立窗口的大小和title值,然后去创建form。

在module目录中再建立一个form目录,在form目录下建立文件BaseForm.js。在Form中设置好参数后,根据配置信息来创建各个fieldSet。这个类的处理很复杂,要处理正常的fieldSet,还要处理tab ,accordion,以及是否是子模块的Grid的判断,下面的程序里已经简化了。

/**
 * 
 * 一个form窗口的基类,新增、显示、修改、审核、审批等功能继承了这个窗口
 * 
 */

Ext.define('app.view.module.form.BaseForm', {
    extend: 'Ext.form.Panel',
    alias: 'widget.baseform',

    autoScroll: true,

    buttonAlign: 'center',
    initComponent: function () {
        var me = this;
        this.buttons = [];
        this.buttons.push({
            text: '关闭',
            itemId: 'close',
            icon: 'images/button/return.png'
        });
        me.items = [];

        var groups = this.formScheme.tf_schemeGroups, hasTab = false;
        var hasInTabPanel = false; // 是否有嵌在页里面的tab,
        var inTabPanel;
        Ext.each(groups, function (group) {
            group.tf_numCols = group.tf_numCols || me.formScheme.tf_numCols;
            hasTab = hasTab || (group.tf_displayMode == 'tab');
            hasInTabPanel = hasInTabPanel
                    || (group.tf_displayMode == 'intabpanel');
        });
        if (hasTab) {
            var tabpanel = {
                xtype: 'tabpanel',
                frame: false,
                border: false,
                bodyPadding: '5 5 5 5',
                items: []
            };
            groups[0].tf_displayMode = 'tab'; // 如果第一个tab忘了设置
            var nowtab;

            Ext.each(groups, function (group) {
                if (group.tf_displayMode == 'tab') {
                    if (nowtab)
                        tabpanel.items.push(nowtab);
                    nowtab = {
                        xtype: 'container',
                        title: group.tf_formGroupName,
                        items: []
                    };
                }
                nowtab.items.push(me.createFieldSetOrSubModule(group));

            });
            tabpanel.items.push(nowtab);
            me.items = tabpanel;
        } else {
            me.bodyStyle = 'padding : 5px 5px 0';
            Ext.each(groups, function (group) {
                if (group.tf_displayMode == 'intabpanel') {
                    inTabPanel = {
                        xtype: 'tabpanel',
                        frame: false,
                        border: false,
                        height: 400,
                        items: []
                    };
                    Ext.apply(inTabPanel, me
                                    .getOtherSetting(group.tf_otherSetting))
                    me.items.push(inTabPanel);
                } else if (group.tf_displayMode == 'intab') {
                    var t = me.createFieldSetOrSubModule(group);
                    t.title = group.tf_formGroupName;
                    inTabPanel.items.push(t)
                } else
                    me.items.push(me.createFieldSetOrSubModule(group))

            })
        }
        me.callParent(arguments);
    },

    getOtherSetting: function (str) {
        if (!str)
            return {}
        else
            return Ext.decode('{' + str + '}', true)

    },

    createFieldSetOrSubModule: function (group) {
        var me = this;

        return Ext.create('app.view.module.form.FieldSet', {
            autoScroll: true,
            viewModel: this.getViewModel(),
            schemeGroup: group,
            numCols: group.tf_numCols
        })

    },

    initForm: function () {

    },

    // 不是grid中调用的显示某条记录的信息,可能是其他模块点击namefields来调用的
    setRecordId: function (id) {
        var me = this;
        this.module.model.load(id, {
            success: function (record, operation, success) {
                // success中的record中返回的raw 数据,是字符串,没有经过decode,要自己转成对象
                me.setData(Ext.create(me.module.model, Ext.decode(record.raw)));
            }
        });
    },

    setData: function (model) {
        this.data = model;
        // this.getForm().reset();
        if (this.data) {
            // Ext.suspendLayouts();
            this.getForm().loadRecord(this.data);
            // Ext.resumeLayouts(true);
        } else
            this.getForm().reset();
        // 检查form中是否有子模块,如果有则刷新
    }

});

Form的控件创建好以后,会继续创建每一个FieldSet的内容。在form目录中加入文件FieldSet.js。在这个FieldSet中,暂时还没有加入字段的生成。

/**
 * 
 * 一个form窗口的基类,新增、显示、修改、审核、审批等功能继承了这个窗口
 * 
 */

Ext.define('app.view.module.form.BaseForm', {
    extend: 'Ext.form.Panel',
    alias: 'widget.baseform',

    autoScroll: true,

    buttonAlign: 'center',
    initComponent: function () {
        var me = this;
        this.buttons = [];
        this.buttons.push({
            text: '关闭',
            itemId: 'close',
            icon: 'images/button/return.png'
        });
        me.items = [];

        var groups = this.formScheme.tf_schemeGroups, hasTab = false;
        var hasInTabPanel = false; // 是否有嵌在页里面的tab,
        var inTabPanel;
        Ext.each(groups, function (group) {
            group.tf_numCols = group.tf_numCols || me.formScheme.tf_numCols;
            hasTab = hasTab || (group.tf_displayMode == 'tab');
            hasInTabPanel = hasInTabPanel
                    || (group.tf_displayMode == 'intabpanel');
        });
        if (hasTab) {
            var tabpanel = {
                xtype: 'tabpanel',
                frame: false,
                border: false,
                bodyPadding: '5 5 5 5',
                items: []
            };
            groups[0].tf_displayMode = 'tab'; // 如果第一个tab忘了设置
            var nowtab;

            Ext.each(groups, function (group) {
                if (group.tf_displayMode == 'tab') {
                    if (nowtab)
                        tabpanel.items.push(nowtab);
                    nowtab = {
                        xtype: 'container',
                        title: group.tf_formGroupName,
                        items: []
                    };
                }
                nowtab.items.push(me.createFieldSetOrSubModule(group));

            });
            tabpanel.items.push(nowtab);
            me.items = tabpanel;
        } else {
            me.bodyStyle = 'padding : 5px 5px 0';
            Ext.each(groups, function (group) {
                if (group.tf_displayMode == 'intabpanel') {
                    inTabPanel = {
                        xtype: 'tabpanel',
                        frame: false,
                        border: false,
                        height: 400,
                        items: []
                    };
                    Ext.apply(inTabPanel, me
                                    .getOtherSetting(group.tf_otherSetting))
                    me.items.push(inTabPanel);
                } else if (group.tf_displayMode == 'intab') {
                    var t = me.createFieldSetOrSubModule(group);
                    t.title = group.tf_formGroupName;
                    inTabPanel.items.push(t)
                } else
                    me.items.push(me.createFieldSetOrSubModule(group))

            })
        }
        me.callParent(arguments);
    },

    getOtherSetting: function (str) {
        if (!str)
            return {}
        else
            return Ext.decode('{' + str + '}', true)

    },

    createFieldSetOrSubModule: function (group) {
        var me = this;

        return Ext.create('app.view.module.form.FieldSet', {
            autoScroll: true,
            viewModel: this.getViewModel(),
            schemeGroup: group,
            numCols: group.tf_numCols
        })

    },

    initForm: function () {

    },

    // 不是grid中调用的显示某条记录的信息,可能是其他模块点击namefields来调用的
    setRecordId: function (id) {
        var me = this;
        this.module.model.load(id, {
            success: function (record, operation, success) {
                // success中的record中返回的raw 数据,是字符串,没有经过decode,要自己转成对象
                me.setData(Ext.create(me.module.model, Ext.decode(record.raw)));
            }
        });
    },

    setData: function (model) {
        this.data = model;
        // this.getForm().reset();
        if (this.data) {
            // Ext.suspendLayouts();
            this.getForm().loadRecord(this.data);
            // Ext.resumeLayouts(true);
        } else
            this.getForm().reset();
        // 检查form中是否有子模块,如果有则刷新
    }

});

以过以上步骤,加入了 window-form-fieldset的三级控件的创建,下面来显示一下结果。在GridToolbar.js中,给修改按钮加个事件:

{
    text : '修改',
    glyph : 0xf044,
    itemId : 'edit',
    handler : 'editRecord'
}

在ModuleController.js中加入函数:

editRecord : function(button) {
    var window = Ext.widget('basewindow',{
        viewModel : this.getView().getViewModel()
    });
    window.show();
},

在Module.js 的uses 中加入 'app.view.module.window.BaseWindow',这样就可以运行了。

srcvhrj3

下面一节将会加入不同种类的field。

原文地址:https://www.cnblogs.com/niejunchan/p/4997022.html