View 层 -- 以国家为例
1. 显示 数据库的 table
页面效果
对应代码:
1 <table id="dg" title="国家信息" class="easyui-datagrid" style="100%;height:0px"
2 toolbar="#toolbar" fitColumns="true" sortName="CODE" sortOrder="asc"
3 data-options="rownumbers:true,singleSelect:true,pagination:true,pageSize:10"
4 >
5 <thead>
6 <tr>
7 <th field="CODE" width="50" sortable="true">国家编码</th>
8 <th field="NAME_ZH" width="50">中文简称</th>
9 <th field="NAME_ZH_FULL" width="50">中文全称</th>
10 <th field="NAME_EN" width="50">英文简称</th>
11 <th field="NAME_EN_FULL" width="50">英文全称</th>
12 <th field="REMARK" width="50">备注</th>
13 </tr>
14 </thead>
15 </table>
2. 增删改查条件的添加
<div id="toolbar">
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-add" plain="true" onclick="newObj()">添加国家</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-edit" plain="true" onclick="editObj()">编辑</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-remove" plain="true" onclick="deleteObj()">删除</a>
<table class='f-tb' style="width:auto;">
<tr>
<td class="no-bd-t">
国家编码:
<input type="text" class='easyui-validatebox' id="key_code" name="key_code" data-options="prompt:'请输入国家编码'">
</td>
<td class="no-bd-t">
<div class="datagrid-btn-separator"></div>
</td>
<td class="no-bd-t">
中文简称:
<input type="text" class='easyui-validatebox' id="key_name_zh" name="key_name_zh" data-options="prompt:'支持部分查询'">
</td>
<td class="no-bd-t">
<div class="datagrid-btn-separator"></div>
</td>
<td class="no-bd-t">
英文简称:
<input type="text" class='easyui-validatebox' id="key_name_en" name="key_name_en" data-options="prompt:'支持部分查询'">
</td>
<td class="no-bd-t">
<div class="datagrid-btn-separator"></div>
</td>
<td class="no-bd-t">
<a href="javascript:;" id="search-btn" class="easyui-linkbutton" onclick="searchObj()" iconCls="icon-search" data-options="plain:true">查询</a>
</td>
<td class="no-bd-t">
<div class="datagrid-btn-separator"></div>
</td>
<td class="no-bd-t">
<a href="javascript:;" id="clear-btn" class="easyui-linkbutton" onclick="clearObj()" iconCls="icon-delete" data-options="plain:true">清空查询条件</a>
</td>
<td class="no-bd-t">
<div class="datagrid-btn-separator"></div>
</td>
</tr>
</table>
</div>
3.
添加和修改弹出框的实现
<div id="dlg" class="easyui-dialog" style="width:400px;height:350px;padding:10px 20px"
closed="true" buttons="#dlg-buttons">
<div class="ftitle">国家信息</div>
<form id="fm" method="post" novalidate>
<div class="fitem" style="display:none;">
<label>国家编码:</label>
<input name="ID" class="easyui-textbox" >
</div>
<div class="fitem">
<label>国家编码:</label>
<input name="CODE" class="easyui-textbox" required="true">
</div>
<div class="fitem">
<label>中文简称:</label>
<input name="NAME_ZH" class="easyui-textbox" required="true">
</div>
<div class="fitem">
<label>中文全称:</label>
<input name="NAME_ZH_FULL" class="easyui-textbox" >
</div>
<div class="fitem">
<label>英文简称:</label>
<input name="NAME_EN" class="easyui-textbox" required="true">
</div>
<div class="fitem">
<label>英文全称:</label>
<input name="NAME_EN_FULL" class="easyui-textbox">
</div>
<div class="fitem">
<label>备注:</label>
<input name="REMARK" class="easyui-textbox">
</div>
</form>
</div>
<div id="dlg-buttons">
<a href="javascript:void(0)" class="easyui-linkbutton c6" iconCls="icon-ok" onclick="saveObj()" style="width:90px">保存</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-cancel" onclick="javascript:$('#dlg').dialog('close')" style="width:90px">取消</a>
</div>
4.
页面 js 控制代码:
增删改查的方法已经封装到下面的js 中,页面只需简单调用即可
<script type="text/javascript" src="/js/common.js"></script>
<script type="text/javascript">
var url ;
function newObj(){
url = '/base/country/save';
newModel('添加国家',url);
}
function editObj(){
url = '/base/country/update';
editModel(url,"ID");
}
function saveObj(){
saveModel(url);
}
function deleteObj(){
url = '/base/country/delete';
deleteModel(url,"ID");
}
function searchObj(){
$("#dg").datagrid(
{
url : "/base/country/search?CODE="+encodeURI($("#key_code").val())+"&NAME_ZH="+encodeURI($("#key_name_zh").val())+"&NAME_EN="+encodeURI($("#key_name_en").val())
});
$('#dg').datagrid({loadFilter:pagerFilter}).datagrid('load');
}
function clearObj(){
$("#key_code").val('') ;
$("#key_name_zh").val('');
$("#key_name_en").val('');
}
$(function(){
$('#dg').datagrid({loadFilter:pagerFilter,url:"/base/country/getList"}).datagrid('load');
});
</script>
注意上面代码中的 url 一定要先赋值 ,再引用,下面的也一样。因为赋值影响的是下次向后台传递的 url。主要区别在新增 和修改处,感兴趣的同学可以试一下,直接写到方法里面。看看有啥影响。
5. 查询条件的设置与效果
function searchObj(){
$("#dg").datagrid(
{
url : "/base/country/search?CODE="+encodeURI($("#key_code").val())+"&NAME_ZH="+encodeURI($("#key_name_zh").val())+"&NAME_EN="+encodeURI($("#key_name_en").val())
});
$('#dg').datagrid({loadFilter:pagerFilter}).datagrid('load');
}
说明:
- 1. 关键字定义 key_XXXXXX
- 2. 目前后台传向前台的变量名称均为大写,所以在填充这些地方的 input ,或者表格中需要将 filedName 与后台一致
二、 router 的定义
1 var base=require('../../controllers/base/index.js');
2 // var filters=require('../filters');
3
4 module.exports= function(app){
5 /*运输任务管理首页*/
6 app.all("/base/country", base.country.index);
7 app.all("/base/country/save", base.country.save);
8 app.all("/base/country/delete", base.country.delete);
9 app.all("/base/country/search", base.country.getList);
10 app.all("/base/country/update", base.country.update);
11 app.all("/base/country/getList", base.country.getList);
12
13 }
我一个模块的 router 都定义在一个文件中方便管理:稍后给出整个项目的文件夹划分
3. controller 的实现
controller 中的方法,是在router 中跳转时,使用的
废话不说上代码
1 var models = require("../../models");
2 var utils = require("../../lib/utils");
3
4 // Copyright 2014 www.satanrabbit.com. All Rights Reserved.
5 /**
6 * @fileoverview controller 基础数据 国家信息管理
7 * @author satanrabbit@qq.com
8 */
9 /*==============================================================*/
10 /* Table: "t_country" */
11 /*==============================================================*/
12 /*
13 drop table "t_country" cascade constraints;
14 create global temporary table "t_country"
15 (
16 "code" VARCHAR2(20) not null,
17 "name_zh" varchar2(50) not null,
18 "name_zh_full" VARCHAR2(200),
19 "name_en" VARCHAR2(50) not null,
20 "name_en_full" vARCHAR2(200),
21 "remark" varchar2(200),
22 constraint PK_T_COUNTRY primary key ("code")
23 );
24
25 comment on table "t_country" is
26 '基础信息维护,国家';
27
28 comment on column "t_country"."code" is
29 '国家代码,主键';
30
31 comment on column "t_country"."name_zh" is
32 '国家中文简称';
33
34 comment on column "t_country"."name_zh_full" is
35 '国家中文全称';
36
37 comment on column "t_country"."name_en" is
38 '国家英文简称';
39
40 comment on column "t_country"."name_en_full" is
41 '国家英文全称';
42
43 comment on column "t_country"."remark" is
44 '备注';
45 */
46
47
48 /**
49 * 基础数据管理--国家首页
50 * @param {Object} req request
51 * @param {Object} res response
52 */
53 exports.index=function(req,res){
54 res.render('base/country/index.ejs');
55 }
56
57 /**
58 * 基础数据管理--国家新建
59 * @param {Object} req request
60 * @param {Object} res response
61 */
62 exports.save=function(req,res){
63 var country = new Country(req);
64 // console.log(country);
65 models.baseCountry.saveCountry(country,function(err){
66 if(err){
67 // res.send(err);
68 utils.sendHJ(res,{result:"fail",msg:"保存失败!"});
69 }else{
70 // res.send(err);
71 utils.sendHJ(res,{result:"success",msg:"保存成功!"});
72 }
73 });
74 }
75
76 /**
77 * 基础数据管理--国家删除
78 * @param {Object} req request
79 * @param {Object} res response
80 */
81 exports.delete=function(req,res){
82 var id = req.param("id");
83 console.log("-----" + id);
84 models.baseCountry.deleteCountry(id,function(err,results){
85 if(err){
86 // res.send(err);
87 utils.sendHJ(res,{result:"fail",msg:"删除失败!"});
88 }else{
89 // res.send("aha:" + err);
90 utils.sendHJ(res,{result:"success",msg:"删除成功!"});
91 }
92 });
93 }
94
95
96 /**
97 * 基础数据管理--国家修改
98 * @param {Object} req request
99 * @param {Object} res response
100 */
101 exports.update=function(req,res){
102 var country = new Country(req);
103 console.log(country);
104 models.baseCountry.updateCountry(country,function(err){
105 if(err){
106 // res.send(err);
107 utils.sendHJ(res,{result:"fail",msg:"保存失败!"});
108 }else{
109 // res.send(err);
110 utils.sendHJ(res,{result:"success",msg:"保存成功!"});
111 }
112 });
113 }
114
115
116
117 /**
118 * 基础数据管理--查询所有,以及根据条件进行查询
119 * @param {Object} req request
120 * @param {Object} res response
121 */
122 exports.getList=function(req,res){
123 var country = new Country(req);
124 // console.log(country);
125
126 //page 和 pageSize 暂时没有用处,分页通过前台的js控制
127 var page=0,pageSize=10,sorter="code",order="desc",type=0;
128 if(req.param("sorter")&&utils.trim(req.param("sorter"))!=""){
129 sorter=utils.trim(req.param("sorter"));
130 }
131 if(req.param("order")&&utils.trim(req.param("order"))!=""){
132 order=utils.trim(req.param("order"));
133 }
134 //真正的处理查询功能在model 中实现,controller 中只是调用
135 models.baseCountry.getList(country,page,pageSize,sorter,order,function(err,rows){
136 if(err){
137 res.send(500,{error:err});
138 }else{
139 var str = JSON.stringify(rows);
140 //由于尝试 直接查询 条数后 传值出现问题,故在util中新增方法,直接根据json返回条数信息,
141 var total = utils.getTotalFromOneJson(str);
142 console.log(total);
143 utils.sendHJ(res,{total:total,rows:rows});
144 }
145 });
146 }
147
148 //构建pojo,将前台传入的大写,转化为小写。并获得所有参数值
149 var Country = function(req){
150 if(req.param('ID')&&utils.trim(req.param('ID'))!=""){
151 this.id=utils.trim(req.param('ID'));
152 }else{
153 this.id = "";
154 }
155 if(req.param('CODE')&&utils.trim(req.param('CODE'))!=""){
156 this.code=utils.trim(req.param('CODE'));
157 }else{
158 this.code = "";
159 }
160 if(req.param('NAME_ZH')&&utils.trim(req.param('NAME_ZH'))!=""){
161 this.name_zh=(utils.trim(req.param('NAME_ZH')));
162 }else{
163 this.name_zh = "";
164 }
165 if(req.param('NAME_ZH_FULL')&&utils.trim(req.param('NAME_ZH_FULL'))!=""){
166 this.name_zh_full=utils.trim(req.param('NAME_ZH_FULL'));
167 }else{
168 this.name_zh_full = "";
169 }
170 if(req.param('NAME_EN')&&utils.trim(req.param('NAME_EN'))!=""){
171 this.name_en=utils.trim(req.param('NAME_EN'));
172 }else{
173 this.name_en = "";
174 }
175 if(req.param('NAME_EN_FULL')&&utils.trim(req.param('NAME_EN_FULL'))!=""){
176 this.name_en_full=utils.trim(req.param('NAME_EN_FULL'));
177 }else{
178 this.name_en_full = "";
179 }
180 if(req.param('REMARK')&&utils.trim(req.param('REMARK'))!=""){
181 this.remark=utils.trim(req.param('REMARK'));
182 }else{
183 this.remark = "";
184 }
185 console.log(this.name_en);
186 }
代码中有 注释,应该看的差不多了。
4. model 层的定义和实现
我在model 层中,每一个模块 都建一个文件夹,然后有一个index.js 在这个里面 在最外层的index 文件中。声明所有的 该模块下 的 model,然后可以通过 (模块名+model名).方法名 的方式进行调用
你看 , 外层的index.js 的代码: baseCountry = base+ country 模块名+model 名。。。。。。。。
exports.baseCountry=require("./base/country.js");
model层代码样板:
1 var config=require("../oracleConfig.json");
2 var oracle = require("../oracleConn");
3
4 exports.saveCountry = function(country,cb){
5
6 oracle.connect(config, function(err, connection) {
7 if (err) {
8 console.log(err);
9 } else {
10 console.log(country + "---" + country.code);
11 connection.execute("INSERT INTO t_base_country(code,name_zh,name_zh_full,name_en,name_en_full,remark) values(:1,:2,:3,:4,:5,:6) ", [country.code,country.name_zh,country.name_zh_full,country.name_en,country.name_en_full,country.remark],
12 // connection.execute("INSERT INTO t_base_country(code,name_zh,name_zh_full,name_en,name_en_full,remark) values(:1,:2,:3,:4,:5,:6) ", ["12","121","1212","1212","1212","1212"],
13 function(err,results) {
14 console.log(err);
15 if (err) {
16 console.log(err);
17 cb(err);
18 } else {
19 // country.bookID = results.insertId;
20 console.log(results);
21 cb(err, results);
22 }
23 //链接最好在 执行 sql 之后立马结束,不要再execute之外结束
24 connection.close();
25 });
26 }
27 });
28 }
29
30 // 根据传入的id 来进行删除,此处的id 不一定字段名 是id ,只是表示主键的意思
31 exports.deleteCountry = function(id,cb){
32
33 oracle.connect(config, function(err, connection) {
34 if (err) {
35 console.log(err);
36 } else {
37 connection.execute("delete from t_base_country where id=:1 ", [id],
38 function(err,results) {
39 console.log(err);
40 if (err) {
41 console.log(err);
42 cb(err);
43 } else {
44 // country.bookID = results.insertId;
45 console.log(results);
46 cb(err, results);
47 }
48 //链接最好在 执行 sql 之后立马结束,不要再execute之外结束
49 connection.close();
50 });
51 }
52 });
53 }
54
55
56 exports.updateCountry = function(country,cb){
57
58 oracle.connect(config, function(err, connection) {
59 if (err) {
60 console.log(err);
61 } else {
62 console.log(country + "---" + country.code);
63 // 执行sql语句
64 connection.execute("update t_base_country set code=:1,name_zh=:2,name_zh_full=:3,name_en=:4,name_en_full=:5,remark=:6 where id=:7 ", [country.code,country.name_zh,country.name_zh_full,country.name_en,country.name_en_full,country.remark,country.id],
65 function(err,results) {
66 console.log(err);
67 if (err) {
68 // console.log(err);
69 cb(err);
70 } else {
71 // country.bookID = results.insertId;
72 // console.log(results);
73 console.log(country.id);
74 cb(err, results);
75 }
76 //链接最好在 执行 sql 之后立马结束,不要再execute之外结束
77 connection.close();
78 });
79 }
80 });
81 }
82
83
84 exports.getList = function(country,page,pageSize,sorter,order,cb){
85 var whereStr=" where 1=1 ";
86 //构造where 条件sql
87 if(country.code!=null && country.code!=""){
88 whereStr += " and code like '%"+country.code + "%'";
89 }
90 if(country.name_zh!=null && country.name_zh!=""){
91 whereStr += " and (name_zh like '%"+country.name_zh + "%' or name_zh_full like '%"+country.name_zh + "%' ) ";
92 }
93 if(country.name_en!=null && country.name_en!=""){
94 whereStr += " and (name_en like '%"+country.name_en + "%' or name_en_full like '%"+country.name_en + "%') ";
95 }
96
97 if(order!="desc"){
98 order="asc";
99 }
100
101 if(sorter!=""){
102 whereStr+= " order by " + sorter + " " + order;
103 }
104
105 var selectSql = " SELECT * FROM t_base_country " + whereStr;
106 // SELECT * FROM (SELECT A.*, ROWNUM RN FROM (SELECT * FROM TABLE_NAME) A WHERE ROWNUM <= 40)WHERE RN >= 21
107 // var selectSql=" select * from ( select A.*,rownum rn from ("+comSql + ") A where rownum<="+ (page+1)*pageSize +")where rn>="+(page*pageSize+1);
108
109 console.log(selectSql);
110 // 进行连接
111 oracle.connect(config, function(err, connection) {
112 if (err) {
113 console.log("connection faild");
114 console.log(err);
115 } else {
116 console.log("connection success");
117 connection.execute(selectSql,[],function(err,results){
118 if(err){
119 cb(err);
120 }else{
121 cb(err,results);
122 }
123 //链接最好在 执行 sql 之后立马结束,不要再execute之外结束
124 connection.close();
125 });
126 }
127 });
128 }
好了,至此,已经连成一条线了。
最终 入口处,这么调用:
<li class="fs">
<a href="/base/country" target="center_frame">国家</a>
</li>
额。。。。写个说明太费劲了, 有啥不明白的再问吧。如果觉得后,可以参考,有好的建议,请及时提出,共同进步。