这一节加入模块自定义字段,并根据这些字段生成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',
width: 100
});
break; case 'Datetime':
Ext.apply(field, {
xtype: 'datecolumn',
align: 'center',
width: 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',
width: 110
});
break;
case 'Float':
Ext.apply(field, {
align: 'center',
xtype: 'numbercolumn',
width: 110
});
break;
case 'Percent':
Ext.apply(field, {
align: 'center',
xtype: 'numbercolumn',
width: 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>');
}
}
});

文件的结构:

13、手把手教你Extjs5(十三)模块字段和Grid列的定义[1]的更多相关文章

  1. 14、手把手教你Extjs5(十四)模块字段和Grid列的定义[2]

    model和columns生成好了,下面要修改一下Module.js和Grid.js中的代码,使其能够协同工作. /** * 一个模块的主控界面的容器,用来安放各个模块控件以及协调他们之间的关系 */ ...

  2. 16、手把手教你Extjs5(十六)Grid金额字段单位MVVM方式的选择

    这一节来完成Grid中的金额字段的金额单位的转换.转换旰使用MVVM特性,总体上和控制菜单的几种模式类似.首先在目录app/view/main/menu下建立文件Monetary.js,用于放金额单位 ...

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

    下面开始设计和完成一个简单的Form的自定义过程.先准备数据,在ModuleModel.js中的data属性下面,加入自定义Form的参数定义,下面的代码中定义了一个新的属性tf_formScheme ...

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

    对于有很多字段的模块在一个grid中显示所有的字段,会显得很臃肿,对于不同的用户其侧重的字段类型也不尽相同,因此就有必要为Grid的列表设计多个方案.在这个自定义系统进行设计的时候,我已经将这部分内容 ...

  5. 19、手把手教你Extjs5(十九)模块Grid的其他功能的设想

    经过对自定义模块和Grid的设计和编码,现在已经能对一个有配置信息的模块来生成界面并进行一些简单的CURD操作.由于这是一个全解释性的前台的架构,因此你想到的任何新主意都可以放到所有的模块中. 比如对 ...

  6. 手把手教Linux驱动2-之模块参数和符号导出

    通过<手把手教Linux驱动1-模块化编程,玩转module>的学习,我们已经掌握了如何向内核加载一个模块,现在我们学习模块之间如何传递参数. 一.给模块传递参数 当我们加载一个模块到Li ...

  7. 23、手把手教你Extjs5(二十三)模块Form的自定义的设计[2]

    在本节中将要加入各种类型的字段,在加入字段的时候由于可以一行加入多个字段,因此层次结构又多了一层fieldcontainer.form里面的主要层次结构如下: form -- fieldSet -- ...

  8. 18、手把手教你Extjs5(十八)模块记录的拖放删除、拖放复制新增

    网页当中的拖放(drag-drop)是比较有趣的操作,extjs5中很好的封装了拖放的动作,也有各种类来支持,但是要学好“拖放”这个东西真是很难,特别是象我这样英语不好的人,看不太懂官网上的说明,做一 ...

  9. 21、手把手教你Extjs5(二十一)模块Form的自定义的设计

    前面几节完成了模块Grid的自定义,模块Form自定义的过程和Grid的过程类似,但是要更复杂一些.先来设计一下要完成的总体目标. 1、可以有多个Form方案,对应于显示.新增.修改.审核.审批等功能 ...

随机推荐

  1. Sanatorium

    Sanatorium time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  2. Android &Swift iOS开发:语言与框架对比

    转载自:http://www.infoq.com/cn/articles/from-android-to-swift-ios?utm_campaign=rightbar_v2&utm_sour ...

  3. NSAttributedString 的21种属性 详解

    原文链接:http://www.jianshu.com/p/09f54730feaa 先看看所有的Key NSFontAttributeName; //字体,value是UIFont对象 NSPara ...

  4. 转:Selenium2.0 click()不生效的解决办法

    除了http://573301735.com/?p=5126讲的,昨天又发现一个让我1个小时生不如死的问题,就是使用两个不同的配置文件来初始化driver,findelement方法获取到的坐标居然不 ...

  5. KNN邻近分类算法

    K邻近(k-Nearest Neighbor,KNN)分类算法是最简单的机器学习算法了.它采用测量不同特征值之间的距离方法进行分类.它的思想很简单:计算一个点A与其他所有点之间的距离,取出与该点最近的 ...

  6. svn log操作

    查看当前文件夹的最近N次提交记录 svn update; svn log --limit <N> -v 含义是:查询最近N次提交记录的详细信息,包括版本号,提交文件列表,log信息 对比某 ...

  7. 剑指offer 连续子序列和

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution { public:     int FindGreatestSumOfSu ...

  8. centos搭建nginx环境

    1.yum install  pcre* 2.wget http://nginx.org/download/nginx-1.7.8.tar.gz 3.tar -zxvf nginx-1.7.8.tar ...

  9. MyEclipse9,MyEclipse10 安装ADT

    Eclipse安装ADT 时步骤是开 Eclipse IDE,进入菜单中的 "Help" -> "Install New Software" ,点击Add ...

  10. FusionCharts使用问题及解决方法(一)-FusionCharts常见问题大全

    当你利用FusionCharts创建图表时报错,原因是多方面的.本文总结了一些常见问题及解决方法供大家参考,希望对大家有帮助. 如果你无法看到任何图表: 如果浏览器中的进度条一直加载,或者右键菜单显示 ...