EXT的奇妙之旅

         初次知道EXT还是通过看一个同事以前做的项目,当时他们用EXT做了一个桌面版的系统,看到就一下被吸引了,心想:"原来WEB版也可以做的这么酷",后来就买了一本有关EXT的书学习,发现EXT有好多面向对象的设计,给我的感觉就是每个JS文件就详单与Java中的类文件一样,学了一段时间之后就想着尝试自己做一个系统玩玩儿,做了一段时间发现,EXT其实还是挺难学的,后来就一直希望能在自己的项目中应用,但是一直没有机会实战,再后来由于项目使用easyui,就又投身到easyui的研究中,就放下了Ext的学习,在不经意间发现Ext已经跟新了好几个版本,最近趁项目运维阶段不是很忙,抽时间用EXT5做了一个系统,以前的东西忘得也差不多了,也是在网上找了一些资料,学习了一下,项目才算初步成型,不过还有很长的路要走啊,希望自己能坚持下去吧。奋斗


项目----项目管理系统

目的是想着一个公司肯定有好多系统,想OA,还有好多商业系统,然后自己就想能不能对这些项目进行一下统一管理呢,这样的话,如果项目里遇到问题还可以参考其他系统的实现,从而实现公司内部技术的共享。


目前项目的成果:

  1. 下图显示的是进入项目的主页的整体布局


点击---》项目信息--》进入项目信息页面



点击人员信息---》进入人员信息界面



点击用户管理---》进入用户管理界面



其他的操作类似就不一一列举了,目前的界面还有和数据库做交互


项目中使用的技术:

前端:Extjs5.0

后台:SpringMVC

服务器:Tomcat

数据库:Mysql

开发工具:eclipse

所有jar包的依赖通过Maven管理


Extjs的搭建过程:


  1. 新建一个Maven项目,过程如下:

      


点击next:



点击next



点击完成即可


2.生成Ext所需环境

需要使用sencha cmd,具体可以参考:http://lingyi.red/using-sencha-cmd-with-ext-js-5


EXT主要代码实现如下:


Main.js


/**
 * This class is the main view for the application. It is specified in app.js as
 * the "autoCreateViewport" property. That setting automatically applies the
 * "viewport" plugin to promote that instance of this class to the body element.
 * 
 * TODO - Replace this content of this view to suite the needs of your
 * application.
 */
Ext.define('webapp.view.main.Main', {
	extend : 'Ext.container.Container',
	requires : [ 'webapp.view.main.MainController',
			'webapp.view.main.MainModel' ],

	uses : [ 'webapp.view.module.Module' ],

	// 设置图标字体文件,只有设置了以后才能用glyph属性
	initComponent : function() {
		Ext.setGlyphFontFamily('FontAwesome');
		
//		this.getViewModel().set('monetary.value','tenthousand');
		
		this.callParent();
	},

	xtype : 'app-main',

	uses : ['webapp.view.main.layout.Center', 'webapp.view.main.layout.Top', 'webapp.view.main.layout.Bottom',
			'webapp.view.main.layout.AccordionMainMenu' ],

	controller : 'main',
	viewModel : {
		type : 'main'
	},

	layout : {
		type : 'border'
	},

	items : [ {
		xtype : 'maintop',
		region : 'north'
	}, {
		xtype : 'mainbottom',
		region : 'south'
	},

	{
		xtype : 'mainmenuaccordion',
		region : 'west', // 左边面板
		width : 250,
		split : true
	}, {
		region : 'center',
		xtype : 'maincenter'

	} ]
});

MainController.js

/**
 * This class is the main view for the application. It is specified in app.js as
 * the "autoCreateViewport" property. That setting automatically applies the
 * "viewport" plugin to promote that instance of this class to the body element.
 * 
 * TODO - Replace this content of this view to suite the needs of your
 * application.
 */
Ext.define('webapp.view.main.MainController', {
	extend : 'Ext.app.ViewController',

	requires : [ 'Ext.window.MessageBox' ],

	uses : [ 'webapp.view.module.Module' ],

	alias : 'controller.main',

	// 选择了主菜单上的菜单后执行
	onMainMenuClick : function(menuitem) {
		var maincenter = this.getView().down('maincenter');

		//获取tab组件
		var tab = maincenter.getComponent(menuitem.moduleName);

		//如果组件没有创建,则添加,否则不在添加,目的就是防止用户重复点击导航栏
		if (tab == null) {

			maincenter.setActiveTab(maincenter.add({
				id : menuitem.moduleName,
				xtype : 'modulepanel',
				moduleName : menuitem.moduleName,
				closable : true,
				reorderable : true
			}));
		}
	},

	setting : function() {
		alert(1);
	}
});


MainModel.js


/**
 * This class is the view model for the Main view of the application.
 */
Ext.define('webapp.view.main.MainModel', {
	extend : 'Ext.app.ViewModel',

	alias : 'viewmodel.main',

	constructor : function() {
		Ext.log('MainModel constructor');
		var me = this;
		// 这一句是关键,如果没有的话,this还没有初始化完成,下面的Ext.apply(me.data,....)这句就会出错
		this.callParent(arguments);
		// 同步调用取得系统参数
		Ext.Ajax.request({
			url : 'application.do',//加载模块信息
			async : false, // 同步
			success : function(response) {
				var text = response.responseText;
				// 将字段串转换成本地变量
				var applicationInfo = Ext.decode(text, true);
				// 把从后台传过来的参数加入到data中去
				Ext.apply(me.data, applicationInfo);
			}
		});
	},

	data : {
		name : '系统导航',

		// 系统信息
		system : {
			name : '项目管理系统',
			iconUrl : ''
		},

		// 单位信息
		service : {
			company : 'XXXX',
			copyright : 'XXXX'
		},

		// 系统菜单的定义,这个菜单可以是从后台通过ajax传过来的
		systemMenu : [ {
			text : '项目管理', // 菜单项的名称
			icon : '', // 菜单顶的图标地址
			glyph : 0,// 菜单项的图标字体的数值
			expanded : true, // 在树形菜单中是否展开
			description : '', // 菜单项的描述
			items : [ {
				text : '项目信息', // 菜单条的名称
				module : 'Global', // 对应模块的名称
				icon : '', // 菜单条的图标地址
				glyph : 0xf0f7
			// 菜单条的图标字体
			}, {
				text : '人员信息',
				module : 'Worker',
				icon : '',
				glyph : 0xf02e
			} ]

		}, {
			text : '知识管理',
			expanded : true,
			items : [ {
				text : '问题管理',
				module : 'Problem',
				glyph : 0xf02d
			}, {
				text : '技术分享',
				module : 'Shared',
				glyph : 0xf03a
			} ]
		}, {
			text : '系统管理',
			expanded : true,
			items : [ {
				text : '用户管理',
				module : 'userMg',
				glyph : 0xf02d
			}, {
				text : '角色管理',
				module : 'Role',
				glyph : 0xf03a
			}, {
				text : '权限管理',
				module : 'Authority',
				glyph : 0xf022
			}, {
				text : '菜单管理',
				module : 'Resource',
				glyph : 0xf0d6
			} ]

		}

		],

	},

	getModuleDefine : function(moduleId) {
		var result = null;
		
		
		Ext.Array.each(this.get('tf_Modules'), function(module) {
			
			
			if (module.tf_moduleId == moduleId + ''
					|| module.tf_moduleName == moduleId) {
				result = module;
				return false;
			}
		})
		return result;
	}

// TODO - add data, formulas and/or methods to support your view
});

Top.js


/**
 * 页面顶部设计
 */
Ext.define('webapp.view.main.layout.Top', {
	extend : 'Ext.toolbar.Toolbar',
	alias : 'widget.maintop', // 定义了这个组件的xtype类型为maintop
	style : 'background-color : #cde6c7',
	uses : [ 'webapp.ux.ButtonTransparent' ],
	defaults : {
		xtype : 'buttontransparent'
	},
	items : [ {
		xtype : 'image',
		bind : { // 数据绑定到MainModel中data的ystem.iconUrl
			hidden : '{!system.iconUrl}', // 如果system.iconUrl未设置,则此image不显示
			src : '{system.iconUrl}' // 根据system.iconUrl的设置来加载图片
		}
	}, {
		xtype : 'label',
		bind : {
			text : '{system.name}' // text值绑定到system.name
		},
		style : 'font-size : 20px; color : blue;'
	}, {
		text : '注销',
		glyph : 0xf011

	}, {
		text : '设置',
		glyph : 0xf013,
		style:'right:auto; left:1200px;top:0px',
		handler:'setting'
	} ]
});

Bottom.js


/**
 * 页面底部实现
 */
Ext.define('webapp.view.main.layout.Bottom', {
	extend : 'Ext.toolbar.Toolbar',
	alias : 'widget.mainbottom',

	uses : [ 'webapp.ux.ButtonTransparent' ],
	defaults : {
		xtype : 'buttontransparent'
	},
	// 背景颜色
	style : 'background-color : #DFEAF2;',

	items : [ {
		bind : {
			text : '服务单位:{service.company}'

		}
	}, {
		bind : {
			text : '©{service.copyright}'
		}
	} ]
});

Center.js


/**
 * 系统界面的主区域,是一个tabpanel,可以有多个tab页面,用来放置各个模块。
 */
Ext
		.define(
				'webapp.view.main.layout.Center',
				{
					extend : 'Ext.tab.Panel',
					alias : 'widget.maincenter',


					closeAction : 'hide',
					autoDestroy : true,
					tabPosition : 'top',

					plugins : [
							{

								ptype : 'tabclosemenu',
								closeAllTabsText : '关闭所有',
								closeOthersTabsText : '关闭其他',
								closeTabText : '关闭',

								extraItemsTail : [
										'-',
										{
											text : '可关闭',
											itemId : 'canclose',
											checked : true,
											hideOnClick : false,
											handler : function(item) {
												item.ownerCt.tabPanel.tab
														.setClosable(item.checked);
											}
										},
										'-',
										{
											text : '登录时自动打开',
											itemId : 'autoopen',
											checked : false,
											hideOnClick : false,
											handler : function(item) {
												if (item.checked)
													Jfok.system
															.addModuleToAutoOpen(item.ownerCt.tabPanel.moduleName);
												else
													Jfok.system
															.deleteModuleToAutoOpen(item.ownerCt.tabPanel.moduleName);
											}
										},
										'-',
										{
											xtype : 'fieldcontainer',
											items : {
												xtype : 'numberfield',
												fieldLabel : '最多打开Tab数',
												itemId : 'maxtab',
												width : 156,
												value : 8,
												maxValue : 20,
												minValue : 3,
												listeners1 : {
													change : function(field,
															newValue, oldValue) {
														Jfok.system
																.setMaxTab(newValue);
													}
												}
											}
										} ],
								listeners : {
									beforemenu : function(menu, tabPanel) {
										// 此插件有bug,需要加入这个参数
										menu.tabPanel = tabPanel;
										if (tabPanel.tab.reorderable) {
											menu.down('#canclose').setChecked(
													tabPanel.tab.closable);
											menu.down('#canclose').enable();
										} else {
											menu.down('#canclose').setChecked(
													false);
											menu.down('#canclose').disable();
										}
										// 如果是有parentFilter的模块,那么自动打开的菜单条隐掉
										// ,上面的'-'也隐掉
										menu.down('#autoopen').setVisible(
												!tabPanel.parentModuleName);
										menu
												.down('#autoopen')
												.previousSibling()
												.setVisible(
														!tabPanel.parentModuleName);

										menu.down('#autoopen')
												.setChecked(false);// Jfok.system
										// .isModuleAutoOpen(tabPanel.moduleName));
										menu.down('#maxtab').setValue(8);// Jfok.system.getMaxTab());
									}
								}
							}, Ext.create('Ext.ux.TabReorderer') ],


				})


折叠菜单的js


/**
 * 折叠菜单实现
 */
Ext.define('webapp.view.main.layout.AccordionMainMenu', {

	extend : 'Ext.panel.Panel',
	alias : 'widget.mainmenuaccordion',
	title : '系统菜单',
	glyph : 0xf0c9,

	layout : {
		type : 'accordion',
		animate : true
	},

	viewModel : 'main',

	initComponent : function() {
		this.items = [];
		var menus = this.getViewModel().get('systemMenu');
		for ( var i in menus) {
			var menugroup = menus[i];
			var accpanel = {
				menuAccordion : true,
				xtype : 'panel',
				title : menugroup.text,
				bodyStyle : {
					padding : '10px'
				},
				layout : 'fit',
				dockedItems : [ {
					dock : 'left',
					xtype : 'toolbar',
					items : []
				} ],
				glyph : menugroup.glyph
			};
			for ( var j in menugroup.items) {
				var menumodule = menugroup.items[j];
				accpanel.dockedItems[0].items.push({
					moduleName:menumodule.module,
					xtype : 'buttontransparent',
					text : this.addSpace(menumodule.text, 12),
					glyph : menumodule.glyph,
					handler : 'onMainMenuClick'
				});
			}
			this.items.push(accpanel);
		}
		this.callParent(arguments);
	},

	addSpace : function(text, len) {
		console.log(text.length);
		var result = text;
		for ( var i = text.length; i < len; i++) {
			result += ' ';
		}
		return result;
	}

});

Module.js


/**
 * 一个模块的主控界面的容器,用来安放各个模块控件以及协调他们之间的关系
 */
Ext.define('webapp.view.module.Module', {
	extend : 'Ext.panel.Panel',

	alias : 'widget.modulepanel',

	requires : [ 'webapp.view.module.ModuleController',
			'webapp.view.module.ModuleModel',
			'webapp.view.module.factory.ModelFactory' ],

	uses : [ 'webapp.view.module.region.Navigate',
			'webapp.view.module.region.Grid', 'webapp.view.module.user.Grid',
			'webapp.view.module.region.WorkerGrid',
			'webapp.view.module.grid.Problem',
			'webapp.view.module.grid.Shared', 'webapp.view.module.grid.Role',
			'webapp.view.module.grid.Authority',
			'webapp.view.module.grid.Resource' ],

	referenceHolder : true,

	controller : 'module',
	bind : {
		title : '{tf_title}' // 这个绑定是有效的,可以根据ModuleModel中的值来设置title
	},
	layout : 'border', // 模块采用border布局

	initComponent : function() {
		// 从MainModel中取得当前模块的定义数据,包括字段和各种设置的信息
		var mainmodel = this.up('app-main').getViewModel();

		this.module = mainmodel.getModuleDefine(this.moduleName);

		var viewmodel = new Ext.create('webapp.view.module.ModuleModel', {
			// 将该模块的定义信息传递给本模块的viewModel
			module : this.module
		});
		this.setViewModel(viewmodel);

		this.glyph = this.getViewModel().get('tf_glyph'); // 由于上面的glyph的bind无效,因此需要在这里加入glyph的设置

		this.model = webapp.view.module.factory.ModelFactory
				.getModelByModule(this.module);
		
		
		this.items = [ {
			xtype : this.moduleName, // 模块的grid显示区域
			region : 'center'
			//store : this.store
		} ]

		this.callParent();
	}

})

ModuleModel.js


Ext.define('webapp.view.module.ModuleModel', {
	extend : 'Ext.app.ViewModel',
	alias : 'viewmodel.module',

	constructor : function() {
		Ext.log('module constructor');
		// 这一句是关键,如果没有的话,this还没有初始化完成,下面的Ext.apply(me.data,....)这句就会出错
		this.callParent(arguments);

		// 取得MainModel.js中取得的这个模块的的初始化信息
		Ext.apply(this.data, this.module)
		
	},

	// 在开发过程中我先用设定好的值放于data中,等以后自定义的时候,data里的值都是从后台取得的
	// 所有数据库里的字段,我都以tf_开头,只是为了表示这是从后台读取过来的

	data : {

		tf_moduleId : null, // 模块ID号:一个数字的ID号,可以根据此ID号的顺序将相同分组的模块放在一块。
		tf_ModuleGroup : null,// 模块分组:模块分到哪个组里,比如说业务模块1、业务模块2、系统设置、系统管理等。
		tf_moduleName : null, // 模块标识:系统中唯一的模块的标识
		tf_title : null,// 模块名称:能够描述此模块信息的名称。
		tf_glyph : null, // 图标字符值
		tf_shortname : null,// 模块简称:如果名称过长,有些地方可以用简称来代替。
		tf_englishName : null,// 模块英文名称:万一要制作英文版,可以用英文名称。
		tf_englishShortName : null, // 模块英文简称:可以用作生成编码字段。
		tf_description : null,// 模块描述:
		tf_remark : null,
		// 备注:


		// 模块的grid方案,可以定义多个方案
		tf_gridSchemes : [],

		// 模块的form方案,可以定义多个方案
		tf_formSchemes : [],

		selectedNames : '' // 选中的记录的names显示在title上

	},

	formulas : {
		// 模块grid方案的选择Combo是否显示
		gridSchemeHidden : function(get) {
			return this.get('tf_gridSchemes').length <= 1;
		}

	},

	// 根据字段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;
	}

})

ModuleController.js


Ext.define('webapp.view.module.ModuleController', {
	extend : 'Ext.app.ViewController',

	requires : [ 'Ext.MessageBox', 'Ext.window.Toast' ],

	alias : 'controller.module',

	init : function() {
		console.log('modulecontroller.init')
	}

})

ModelFactory.js


/**
 * 根据module的数据来生成模块的model
 */
Ext
		.define(
				'webapp.view.module.factory.ModelFactory',
				{

					statics : {
						getModelByModule : function(module) {
							var model;
							
							//在define之前需要判断model是否已经定义过,否则会报错
							if(!Ext.isDefined('webapp.view.model.'+module.tf_moduleName)){
							
								model= Ext
								.define(
										'webapp.view.model.'
												+ module.tf_moduleName,
										{
											extend : 'Ext.data.Model',
											module : module,
											idProperty : module.tf_primaryKey,
											nameFields : module.tf_nameFields,
											titleTpl : module.tf_titleTpl,
											titleTemplate : null,
											fields : this.getFields(module),
											proxy : {
												type : 'rest',
												batchActions : true,
												extraParams : {
													moduleName : module.tf_moduleName
												},
												api : {
													// 在这里加rest/是因为在web.xml中
													// <url-pattern>/rest/*</url-pattern>这一句,spring会根据rest
													// 后面的参数去进行匹配
													//read : 'rest/module/fetchdata.do',
//													update : 'rest/module/update.do',
//													create : 'rest/module/create.do',
//													destroy : 'rest/module/remove.do'
												},
												actionMethods : {
													create : 'POST',
													read : 'GET',
													update : 'PUT',
													destroy : 'DELETE'
												},
												reader : {
													type : 'json',
													root : 'records',
													totalProperty : 'totalCount'
												},
												writer : {
													type : 'json',
													writeRecordId : true,
													writeAllFields : false
												// 没有修改过的字段不加入到update和delete的json中去
												},
												listeners : {
													exception : function(
															proxy,
															response,
															operation) {
														// 将出错信息加到proxy中去,传递到store的sync中显示出错信息,显示后将此属性删除
														proxy.errorInfo = Ext
																.decode(
																		response.responseText,
																		true);
														// 如果出错信息解析出错,则加入一个缺省的
														if (!proxy.errorInfo)
															proxy.errorInfo = {
																resultCode : -1,
																errorMessage : '未知原因:'
																		+ response.responseText
															}
													}
												}
											},

											getTitleTpl : function() {
												if (!this.titleTemplate) {
													if (this.titleTpl)
														this.titleTemplate = new Ext.Template(
																this.titleTpl);
													else
														this.titleTemplate = new Ext.Template(
																'{'
																		+ this.nameFields
																		+ '}');
												}
												return this.titleTemplate
														.apply(this
																.getData())
											},

											// 此条记录是否可以修改
											canEdit : function() {
												if (this.module.tf_hasAuditing
														&& this
																.get('tf_auditinged'))
													return false;
												if (this.module.tf_hasApprove
														&& this
																.get('tf_shNowCount') > 0)
													return false;
												return true;
											},

											// 此条记录是否可以进行操作
											canOperate : function() {
												if (this.module.tf_hasAuditing
														&& this
																.get('tf_auditinged'))
													return false;
												return true;
											},

											// 此条记录是否可以删除
											canDelete : function() {
												if (this.module.tf_hasAuditing
														&& this
																.get('tf_auditinged'))
													return {
														canDelete : false,
														message : '【'
																+ this
																		.getTitleTpl()
																+ '】已进行过审核,不允许进行删除操作!'
													};
												if (this.module.tf_hasApprove
														&& this
																.get('tf_shNowCount') > 0)
													return {
														canDelete : false,
														message : '【'
																+ this
																		.getTitleTpl()
																+ '】正在审批或已经审批完成,不允许进行删除操作!'
													};
												return true;
											},

											// 取得主键值
											getIdValue : function() {
												return this
														.get(this.idProperty);
											},

											// 取得当前记录的名字字段
											getNameValue : function() {
												if (this.nameFields)
													return this
															.get(this.nameFields);
												else
													return null;
											}

										});
							}
							return model;
						},
						// String("String"), Boolean("Boolean"),
						// Integer("Integer"),
						// Date("Date"), Double("Double"), Float("Float");
						// Percent

						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 (fd.tf_fieldType == 'Date') {
									field.dateWriteFormat = 'Y-m-d';
									field.dateReadFormat = 'Y-m-d';
								}
								if (fd.tf_fieldType == 'Datetime')
									field.dateReadFormat = 'Y-m-d H:i:s';
								field.tf_haveAttachment = fd.tf_haveAttachment;
								fields.push(field);
							}
							return fields;

						},

						getTypeByStr : function(str) {
							console.log(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 'Money':
							case 'Percent':
								return 'float';
							default:
								return 'string';
							}
						},

						// 如果是空字符串,返回null
						convertToNull : function(v) {
							return v ? v : null;
						}

					}

				});


下面就是一个展示表格的js,实现都差不多就不一一列举了,以用户管理的表格为例


Ext.define('webapp.view.module.user.Grid', {
	extend : 'Ext.grid.Panel',
	alias : 'widget.userMg',
	uses : [ 'webapp.view.module.region.GridToolbar' ],
	bind : {
		title : '{tf_title}' // 数据绑定到ModuleModel中的tf_title
	},
	
	dockedItems :{
		xtype : 'gridtoolbar', // 按钮toolbar
		dock : 'top',
		grid : this,
		store:this.myStore
	},
	
	

	// 自定义字段的还没有做,先放几个固定的
	columns : [ {
		dataIndex : 'id',
		text : '用户ID',
		width : 250
	}, {
		dataIndex : 'userName',
		text : '用户姓名'
	}, {
		dataIndex : 'email',
		text : '用户邮箱'
	} , {
		dataIndex : 'createDate',
		text : '创建时间'
	}, {
		dataIndex : 'createId',
		text : '创建ID'
	} , {
		dataIndex : 'status',
		text : '状态'
	}    ],
	
})


//	 var myStore = Ext.create('Ext.data.Store', {
//	     model: 'User',
//	     proxy: {
//	         type: 'ajax',
//	         url: '/user/list.do',
//	         reader: {
//	             type: 'json',
//	             rootProperty: 'root'
//	         }
//	     },
//	     autoLoad: true
//	 });

接下来就是一部分java代码的实现


Module.java 用于动态生成点击导航栏菜单是生成项目的Module


/**
 * 模块实体
 * 
 */
@Entity
@Table(name = "t_module")
@SuppressWarnings("serial")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class Module extends BaseEntity {

    /**  */
    private static final long serialVersionUID = 1L;

    @Id
    private Integer tf_moduleId;

    private String tf_ModuleGroup;

    private String tf_moduleName;

    private String tf_title;

    private String tf_glyph;

    private String tf_shortName;

    public Integer getTf_moduleId() {
        return tf_moduleId;
    }

    public void setTf_moduleId(Integer tf_moduleId) {
        this.tf_moduleId = tf_moduleId;
    }

    public String getTf_ModuleGroup() {
        return tf_ModuleGroup;
    }

    public void setTf_ModuleGroup(String tf_ModuleGroup) {
        this.tf_ModuleGroup = tf_ModuleGroup;
    }

    public String getTf_moduleName() {
        return tf_moduleName;
    }

    public void setTf_moduleName(String tf_moduleName) {
        this.tf_moduleName = tf_moduleName;
    }

    public String getTf_title() {
        return tf_title;
    }

    public void setTf_title(String tf_title) {
        this.tf_title = tf_title;
    }

    public String getTf_glyph() {
        return tf_glyph;
    }

    public void setTf_glyph(String tf_glyph) {
        this.tf_glyph = tf_glyph;
    }

    public String getTf_shortName() {
        return tf_shortName;
    }

    public void setTf_shortName(String tf_shortName) {
        this.tf_shortName = tf_shortName;
    }

}

ApplicationController控制器,用于加载Module数据

@Controller
public class ApplicationController {

    @Resource(name = "applicationService")
    private ApplicationService applicationService;

    private Map jsonMap = new HashMap();

    @RequestMapping("/application.do")
    @ResponseBody
    public Map<String, List<Module>> findModules() {

        jsonMap.put("tf_Modules", applicationService.findAll());

        return jsonMap;
    }

    public Map getJsonMap() {
        return jsonMap;
    }

    public void setJsonMap(Map jsonMap) {
        this.jsonMap = jsonMap;
    }

}

ApplicationService


public interface ApplicationService {

    /**
     * @return
     */
    List<Module> findAll();

}

ApplicationServiceImpl


@Service("applicationService")
@Transactional
public class ApplicationServiceImpl implements ApplicationService{

    @Resource(name="applicationDao")
    private ApplicationDao applicationDao;
    
    /**
     * @return
     * @see com.pms.service.ApplicationService#findAll()
     */
    @Override
    public List<Module> findAll() {
        // TODO Auto-generated method stub
        return applicationDao.findAll();
    }

}

ApplicationDao


@Repository("applicationDao")
public class ApplicationDao extends BaseDao<Module> {

    public List<Module> findAll() {

        return findByhql(" from Module where 1=1 ");
    }
}

BaseDao


public class BaseDao<E extends BaseEntity> {

    @PersistenceContext
    private EntityManager entityManager;

    public EntityManager getEntityManager() {
        return entityManager;
    }

    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    /**
     * 添加
     * 
     * @param entity
     * @return
     */
    public E save(E entity) {

        if (entity != null) {
            entityManager.persist(entity);
        }

        return entity;
    }

    /**
     * 更新
     * 
     * @param entity
     * @return
     */
    public E update(E entity) {

        entity = entityManager.merge(entity);

        return entity;
    }

    /**
     * 删除
     * 
     * @param entity
     */
    public void delete(E entity) {

        entityManager.remove(entity);

    }

    /**
     * 根据ID查询
     * 
     * @param entityClass
     * @param id
     * @return
     */
    public E findById(Class<E> entityClass, Integer id) {

        return entityManager.find(entityClass, id);
    }

    /**
     * 根据Hql查询
     * 
     * @param hql
     * @return
     */
    public List<E> findByhql(String hql) {

        Query query = entityManager.createQuery(hql);

        return query.getResultList();
    }

}

         目前就写到这个程度了,由于本人也是一个码农,只有抽时间继续完成其他功能,权限打算使用Shiro实现,而且对Ext也是似懂非懂,需要边学边做,而且这次使用SpringMVC也是初次尝试,因为开发项目用的都是SSH,之所以用SpringMVC就是出于学习的目的。


最后需要感谢:点击打开链接 的作者,因为这个项目的实现是参照该作者的讲解实现,而且有些代码也是基于作者的代码进行了一些改动



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值