跟我一起学extjs5(37--单个模块的设计[5取得模块列表数据])

时间:2022-04-26 23:04:05

跟我一起学extjs5(37--单个模块的设计[5取得模块列表数据])


        写了几个月,总算有点盼头了,最终要从后台取得数据了。后台的spring mvc 和 service 仅仅能简单的说说了,里面加了几十个类。有兴趣的下载了源代码自己看。以下画张通用的模块列表取数据的流程,这个流程是适用于全部的模块。我这个后台处理程序也是对全部的模块进行统一处理,包含数据查找,新增,改动,删除都是同样的。

跟我一起学extjs5(37--单个模块的设计[5取得模块列表数据])

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamZvaw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">



        绘图不是强项。看得懂即可。
        1、grid在渲染好后就会通过Stroe来取得数据;
        2、Stroe会发送ajax请求至后台server,spring mvc 会依据请求找到 ModuleController 中的对应取得数据的函数;
        3、控制器中调用ModuleService中的函数取得数据。
        4、Service再调用 ModuleDAO的函数从数据库中取得数据,然后一级级的返回到Store中。再显示在Grid之中。

        如今我们先做extjs5端的改动。原来的Store使用的是本地数据,如今要改成远程调用的数据,

1、先改动model的生成函数ModelFactory.js。这个函数依据传入的module的定义来生成model,主要生成的有fields属性和proxy。另一些以后要用到的函数。比方推断此条记录能否改动、删除等的函数。

另一个是取得本条记录的标志字段的函数。

/**
* 依据module的数据来生成模块的model
*/
Ext.define('app.view.module.factory.ModelFactory', { statics : {
getModelByModule : function(module) { var model = Ext.define('app.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.moduleFields) {
var fd = module.moduleFields[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 'Float' :
case 'Percent' :
return 'float';
default :
return 'string';
}
}, // 假设是空字符串,返回null
convertToNull : function(v) {
return v ? v : null;
} } });

2、在app.store的文件夹下生成文件GridStore.js。这是grid的Store的类的定义。

Ext.define('app.store.GridStore', {
extend : 'Ext.data.Store', modulePanel : null,
remoteSort : true,
autoLoad : true,
autoSync : true,
leadingBufferZone : 100,
buffered : false, // buffered=true能够无限下拉。可是删除和新增,reload都有问题,临时不用 config : {
extraParams : {},
navigates : []
// 导航属性选中的情况
}, constructor : function(param) {
var me = this;
this.pageSize = 20;
this.extraParams = {};
this.navigates = [];
// 有创建时加进来的导航约束
if (param.modulePanel.param) {
var dnv = param.modulePanel.param.defaultNavigateValues;
this.setDefaultNavigates(dnv);
}
// ///////////
this.callParent(arguments);
}, listeners : {
// 调用proxy进行ajax的时候。将參数加进 store.proxy中,在调用完毕后。删除掉全部的extraParams參数
// 这样model.proxy就能够多store,互相不干扰了
beforeprefetch : function(store) {
for (var i in store.extraParams)
store.proxy.extraParams[i] = store.extraParams[i];
},
// buffered = true ,运行的是 prefetch
prefetch : function(store, records, successful) {
for (var i in store.extraParams)
delete store.proxy.extraParams[i];
}, // buffered = false ,运行的是 load
beforeload : function(store) {
// console.log(store);
for (var i in store.extraParams)
store.proxy.extraParams[i] = store.extraParams[i]; }, load : function(store) {
for (var i in store.extraParams)
delete store.proxy.extraParams[i];
} } });

3、改动app.view.module.Module类。把store 和 model的生成方式都改一下。

			initComponent : function() {
console.log(this.moduleName + ' 正在创建');
// 从MainModel中取得当前模块的定义数据。包含字段和各种设置的信息 var mainmodel = this.up('app-main').getViewModel();
this.module = mainmodel.getModuleDefine(this.moduleName);
var viewmodel = new Ext.create('app.view.module.ModuleModel', {
// 将该模块的定义信息传递给本模块的viewModel
module : this.module
});
this.setViewModel(viewmodel); this.glyph = this.getViewModel().get('tf_glyph'); // 因为上面的glyph的bind无效,因此须要在这里增加glyph的设置
this.model = app.view.module.factory.ModelFactory.getModelByModule(this.module);
this.store = Ext.create('app.store.GridStore', {
module : this.module,
model : this.model,
modulePanel : this
});
this.items = [{
xtype : 'navigate', // 导航区域
region : 'west',

4、后台服务器端在com.jfok.server.controller下增加ModuleController.java,这是spring mvc 的控制类。

package com.jfok.server.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import com.jfok.server.DAO.SystemBaseDAO;
import com.jfok.server.DAO.module.ModuleDAO;
import com.jfok.server.DAO.module.SqlModuleFilter; import com.jfok.server.common.ModuleServiceFunction; import com.jfok.server.hibernate.system._Module;
import com.jfok.server.service.ApplicationService;
import com.jfok.server.service.ModuleService; import com.jfok.shared.module.DataDeleteResponseInfo;
import com.jfok.shared.module.DataFetchResponseInfo;
import com.jfok.shared.module.DataInsertResponseInfo;
import com.jfok.shared.module.DataUpdateResponseInfo; @Controller
@RequestMapping(value = "/module")
/**
* 所有模块的的CRUD都是调用这个类的函数来完毕的Controller里面完毕的
*
* @author jiangfeng
*
*/
public class ModuleController { @Resource
private SystemBaseDAO systemBaseDAO; @Resource
private ModuleService moduleService; @Resource
private ModuleDAO moduleDAO; private static final Log log = LogFactory.getLog(ModuleController.class); /**
* 依据前台的请求取得数据
*/
@RequestMapping(value = "/fetchdata.do", method = RequestMethod.GET)
public @ResponseBody
Map<String, Object> fetchData(String moduleName, Integer start, Integer limit, String sort,
String query, String columns, String navigates, String parentFilter,
HttpServletRequest request) {
DataFetchResponseInfo response = moduleService.fetchDataInner(moduleName, start, limit, sort,
query, columns, navigates, parentFilter, (SqlModuleFilter) null, request);
Map<String, Object> result = new HashMap<String, Object>();
result.put("records", response.getMatchingObjects());
result.put("totalCount", response.getTotalRows());
return result;
} /**
* 新增记录的时候,在后台取得缺省值
*
* @param moduleName
* @param parentFilter
* @param navigates
* @param request
* @return
*/ @RequestMapping(value = "/getnewdefault.do", method = RequestMethod.POST)
public @ResponseBody
Object getRecordNewDefault(String moduleName, String parentFilter, String navigates,
HttpServletRequest request) { return moduleService.getRecordNewDefault(moduleName, parentFilter, navigates, request); } @RequestMapping(value = "/fetchdata.do/{id}", method = RequestMethod.GET)
public @ResponseBody
Object getRecordById(String moduleName, @PathVariable("id") String id, HttpServletRequest request) {
log.debug("依据主键取得模块的一条记录:" + moduleName + "," + id);
Map<String, Object> result = new HashMap<String, Object>();
result.put("totalCount", 1);
List<Object> records = new ArrayList<Object>();
try {
records.add(moduleDAO.getModuleRecord(moduleName, id, request).toString());
} catch (Exception e) {
e.printStackTrace();
}
result.put("records", records);
log.debug("getRecordById返回值:" + result.toString());
return result;
} /**
* 创建一条记录
*
* @param moduleName
* @param inserted
* @param request
* @return
*/
@RequestMapping(value = "/create.do", method = RequestMethod.POST)
public @ResponseBody
DataInsertResponseInfo addWithNoPrimaryKey(String moduleName, @RequestBody String inserted,
HttpServletRequest request) { return add(moduleName, inserted, request);
} @RequestMapping(value = "/create.do/{id}", method = RequestMethod.POST)
public @ResponseBody
DataInsertResponseInfo add(String moduleName, @RequestBody String inserted,
HttpServletRequest request) {
DataInsertResponseInfo result = null;
try {
result = moduleService.add(moduleName, inserted, request);
if (result.getKey() != null) // 假设是空的话,那么就没有保存,错误原因已经在errorMessage里了
result.getRecords().add(
moduleDAO.getModuleRecord(moduleName, result.getKey(), request).toString());
} catch (DataAccessException e) {
e.printStackTrace();
if (result == null)
result = new DataInsertResponseInfo();
result.setResultCode(ModuleService.STATUS_VALIDATION_ERROR);
} catch (Exception e) {
e.printStackTrace();
if (result == null)
result = new DataInsertResponseInfo();
result.getErrorMessage().put("error", e.getMessage());
result.setResultCode(ModuleService.STATUS_FAILURE);
}
return result;
} /**
* 改动记录
*
* @param moduleName
* @param id
* @param oldid
* @param operType
* @param updated
* @param request
* @return
*/
@RequestMapping(value = "/update.do/{id}", method = RequestMethod.PUT)
public @ResponseBody
DataUpdateResponseInfo update(String moduleName, @PathVariable("id") String id, String oldid,
String operType, @RequestBody String updated, HttpServletRequest request) { DataUpdateResponseInfo result = null;
_Module module = ApplicationService.getModuleWithName(moduleName);
// 假设主键值改动了,那么先进行主键的改动
if (oldid != null && (!oldid.equals(id))) {
try {
result = moduleService.changeRecordId(moduleName, id, oldid);
} catch (ConstraintViolationException e) {
e.printStackTrace();
result = new DataUpdateResponseInfo();
if (e.getCause().toString().toLowerCase().indexOf("primary key") >= 0)
result.getErrorMessage().put(module.getTf_primaryKey(), "改动过后的主键与原有的主键值反复! ");
else
result.getErrorMessage().put(module.getTf_primaryKey(), "当前主键与子模块有约束关系。不能够改动!");
result.setResultCode(ModuleService.STATUS_VALIDATION_ERROR);
}
if (!result.getResultCode().equals(0))
return result;
}
// 改动记录
try {
result = moduleService.update(moduleName, id, operType, updated, request);
result.getRecords().add(moduleDAO.getModuleRecord(moduleName, id, request).toString());
} catch (DataAccessException e) {
result = new DataUpdateResponseInfo();
result.setResultCode(ModuleService.STATUS_VALIDATION_ERROR);
} catch (Exception e) {
e.printStackTrace();
result = new DataUpdateResponseInfo();
result.getErrorMessage().put("error", e.getMessage());
result.setResultCode(ModuleService.STATUS_FAILURE);
}
return result;
} /**
* 删除记录
*
* @param moduleName
* @param id
* @param request
* @return
*/
@RequestMapping(value = "/remove.do/{id}", method = RequestMethod.DELETE)
public @ResponseBody
DataDeleteResponseInfo remove(String moduleName, @PathVariable String id,
HttpServletRequest request) {
DataDeleteResponseInfo result = null;
try {
result = moduleService.remove(moduleName, id, request);
} catch (DataAccessException e) {
result = new DataDeleteResponseInfo();
String errormessage = ModuleServiceFunction.addPK_ConstraintMessage(e, moduleName);
result.setResultMessage(-1, errormessage != null ? errormessage
: "请检查与本记录相关联的其它数据是否所有清空!<br/>");
} catch (Exception e) {
result = new DataDeleteResponseInfo();
result.setResultMessage(-1, e.getMessage());
}
return result;
} @RequestMapping(value = "/removerecords.do")
public @ResponseBody
DataDeleteResponseInfo removeRecords(String moduleName, String ids, String titles,
HttpServletRequest request) {
DataDeleteResponseInfo result = null;
String[] idarray = ids.split(",");
String[] titlearray = titles.split("~~"); result = new DataDeleteResponseInfo(); for (int i = 0; i < idarray.length; i++) {
try {
DataDeleteResponseInfo recordDeleteResult = moduleService.remove(moduleName, idarray[i],
request);
if (recordDeleteResult.getResultCode() == 0) result.getOkMessageList().add(titlearray[i]);
else {
if (recordDeleteResult.getErrorMessageList().size() > 0)
result.getErrorMessageList().add(
"【" + titlearray[i] + "】" + recordDeleteResult.getErrorMessageList().get(0));
else
result.getErrorMessageList().add("【" + titlearray[i] + "】" + "未知错误!");
}
} catch (DataAccessException e) {
String errormessage = ModuleServiceFunction.addPK_ConstraintMessage(e, moduleName); result.getErrorMessageList().add(
"【" + titlearray[i] + "】" + (errormessage != null ? errormessage : "关联的数据未清空!"));
} catch (Exception e) {
result.getErrorMessageList().add("【" + titlearray[i] + "】" + e.getMessage());
}
}
result.setResultCode(result.getErrorMessageList().size());
return result;
} }

5、在service包中增加ModuleService.java,用来完毕查询,新增,删除。改动的功能。

        6、增加ModuleDAO.java ,用来依据模块名称。起始行,终止行,筛选条件等来从数据库中取得数据。这些类太多了,就不一一写明了。




跟我一起学extjs5(37--单个模块的设计[5取得模块列表数据])的更多相关文章

  1. 跟我extjs5&lpar;38--单个模块的设计&lbrack;6获得模块列表数据&rsqb;&rpar;

    跟我extjs5(38--单个模块的设计[6获得模块列表数据])         在程序的前一个表以及,据的执行过程. 在菜单中选择 "系统管理"--"模块分组&quot ...

  2. &lbrack;译文&rsqb;Domain Driven Design Reference(三)—— 模型驱动设计的构建模块

    本书是Eric Evans对他自己写的<领域驱动设计-软件核心复杂性应对之道>的一本字典式的参考书,可用于快速查找<领域驱动设计>中的诸多概念及其简明解释. 其它本系列其它文章 ...

  3. 跟我一起学extjs5&lpar;11--自己定义模块的设计&rpar;

    跟我一起学extjs5(11--自己定义模块的设计)        从这一节開始我们来设计并完毕一个自己定义模块.我们先来确定一个独立的模块的所能定义的一些模块信息. 下面信息仅仅是我自己在开发过程中 ...

  4. 跟我一起学extjs5&lpar;13--运行菜单命令在tabPanel中显示模块&rpar;

    跟我一起学extjs5(13--运行菜单命令在tabPanel中显示模块)         上面设计好了一个模块的主界面,以下通过菜单命令的运行来把这个模块增加到主界面其中. 在MainModule. ...

  5. 跟我一起学extjs5&lpar;42--单个模块的数据新增方式&rpar;

    跟我一起学extjs5(42--单个模块的数据新增方式)         前面的章节中已经增加了一个自己定义的模块,而且能够进行数据的新增.改动.删除的操作了,在这个基础上就能够大作文章了. 这一节来 ...

  6. 跟我一起学extjs5&lpar;22--模块Form的自己定义的设计&rpar;

    跟我一起学extjs5(22--模块Form的自己定义的设计)         前面几节完毕了模块Grid的自己定义,模块Form自己定义的过程和Grid的过程类似,可是要更复杂一些.先来设计一下要完 ...

  7. 跟我一起学extjs5&lpar;18--模块的新增、改动、删除操作&rpar;

    跟我一起学extjs5(18--模块的新增.改动.删除操作)         上节在Grid展示时做了一个金额单位能够手工选择的功能,假设你要增加其它功能.也仅仅要依照这个模式来操作即可了,比方说你想 ...

  8. 跟我一起学extjs5&lpar;24--模块Form的自己定义的设计&lbrack;2&rsqb;&rpar;

    跟我一起学extjs5(24--模块Form的自己定义的设计[2])         在本节中将要增加各种类型的字段,在增加字段的时候因为能够一行增加多个字段,因此层次结构又多了一层fieldcont ...

  9. 跟我一起学extjs5&lpar;16--各种Grid列的自己定义渲染&rpar;

    跟我一起学extjs5(16--各种Grid列的自己定义渲染)         Grid各列已经可以展示出来了.列的类型包含字符型,整型,浮点型,货币型,百分比型,日期型和布尔型,我自己定义了各种类型 ...

随机推荐

  1. Android开发学习—— Fragment

    #Fragment* 用途:在一个Activity里切换界面,切换界面时只切换Fragment里面的内容* 生命周期方法跟Activity一致,可以理解把其为就是一个Activity* 定义布局文件作 ...

  2. cout输出控制——位数和精度控制

    刷到一道需要控制输出精度和位数的题目 刚开始以为单纯使用 iomanip 函数库里的 setprecision 就可以,但 OJ 给我判了答案错误,后来一想这样输出并不能限制位数只能限制有效位数. 比 ...

  3. Building OpenCASCADE on Debian

    Building OpenCASCADE on Debian eryar@163.com Abstract. When you are familiar with OpenCASCADE on Win ...

  4. less 快捷操作

    查找操作: /pattern    向前查找包含pattern的行 ?pattern 向后查找包含pattern的行 n 查找下一个pattern 的行 N 查找上一个pattern的行 ESC-u ...

  5. IdHttpServer实现webservice

    IdHttpServer实现webservice   朋友有个项目,通信协议使用HTTP,数据序列使用BIN(二进制).他不知道要选用何种技术方案. REST webservice是http+json ...

  6. c&plus;&plus; 09

    一.数据结构 程序设计=数据结构+算法 1.逻辑结构 1)集合:元素之间没有联系. 2)线性结构:元素之间存在前后顺序. 3)树形结构:元素之间存在一对多的父子关系. 4)图状结构:元素之间存在多对多 ...

  7. 深入理解Scala的隐式转换系统

    摘要: 通过隐式转换,程序员可以在编写Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来,这种特性可以极大的减少代码量,忽略那些冗长,过于细节的代码.   使用方式: 1. ...

  8. Tomcat配置Web默认页面

    1.在web.xml中配置要加载的首页 <welcome-file-list> <welcome-file>Tiring-room/index.jsp</welcome- ...

  9. 第三次Java作

  10. &lpar;字典序问题&rpar; nyoj1542-最小字符串

    题目描述: 给你一个由小写字母组成的字符串,最多删除其中一个字符,使其字典序最小. 字典序概念在数学中,字典或词典顺序(也称为词汇顺序,字典顺序,字母顺序或词典顺序)是基于字母顺序排列的单词按字母顺序 ...