ddms是基于express的一个表单管理系统,今天抽时间看了下它的代码,其实算不上源码学习,只是对它其中一些小的开发技巧做一些记录,希望以后在项目开发中能够实践下。

  • 数据层封装

    • 模块只对外暴露model,由业务层完成具体数据操作;
    • 利用mongoose的schema的static属性,扩展常用、基础的操作
var form = new Schema({
user: {type: ObjectId, ref: 'User'},
project: {type: ObjectId, ref: 'Project'},
sid: {type: String, unique: true,'default': shortid.generate },
title: {
type: String,
required: true,
default: 'New Form'
},
desc: String,
createDateTime: {
type: Date,
default: Date.now
},
updateDateTime: {
type: Date,
default: Date.now
},
schemata: Mixed
}); form.static({
list: function (callback) {
return this.find()
.populate('user',{_id: 1,name: 1,email: 1,role: 1})
.populate('project',{_id: 1,name: 1,desc: 1})
.sort({_id: -1})
.exec(callback)
},
listByProjectId: function (projectid,callback) {
return this.find({project: projectid})
.populate('user',{_id: 1,name: 1,email: 1,role: 1})
.populate('project',{_id: 1,name: 1,desc: 1})
.sort({_id: -1})
.exec(callback);
}
}); module.exports = mongoose.model('Form', form);
  • 充分利用schema type特性

    • 充分利用schema type的例如getter\setter\validate等 参考:http://mongoosejs.com/docs/2.7.x/docs/schematypes.html。可以将原本业务层的很多处理直接交给mongodb.
var userSchema = new Schema({
email: {
type: String,
required: true, //需要校验
  //给字段存储前线全部小写处理
set: function (value) {
return value.trim().toLowerCase()
},
  //校验的方法
validate: [
function (email) {
return (email.match(/[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/i) != null)
},
'Invalid email'
]
},
//。。。。
twitter: Mixed
});
  • 利用ref来实现join,可以存在多个,如下:
var form = new Schema({
user: {type: ObjectId, ref: 'User'},
project: {type: ObjectId, ref: 'Project'},
sid: {type: String, unique: true,'default': shortid.generate },
form.static({
list: function (callback) {
return this.find()
.populate('user',{_id: 1,name: 1,email: 1,role: 1})
.populate('project',{_id: 1,name: 1,desc: 1})
.sort({_id: -1})
.exec(callback)
},
listByProjectId: function (projectid,callback) {
return this.find({project: projectid})
.populate('user',{_id: 1,name: 1,email: 1,role: 1})
.populate('project',{_id: 1,name: 1,desc: 1})
.sort({_id: -1})
.exec(callback);
}
});
  • 充分利用app.use

    • app.use在express中类似servlet里的filter,属于一种过滤器,它会在每个http请求中被调用
    • ddms通过app.use向req对象中添加model
//app.js中
app.use(function (req, res, next) {
if (!models.User) return next(new Error("No models."));
req.models = models;
return next();
}); //route.js中
exports.showListByProjectId = function (req, res, next) {
var pid = req.params.projectid;
var pp = Promise.resolve( req.models.Project.findOne({_id: pid}) );
var fp = Promise.resolve( req.models.Form.listByProjectId(pid) ); Promise.all([pp,fp])
.then(function(docs){
res.render('forms/list', {project: docs[0],forms: docs[1]});
}).catch(function (error) {
return next(error);
});
};
  • 采用bluebird的promise库做同步

之前一直用async,看了下promise,感觉非常清爽,同上例代码

  • 利用app.get的多callback实现中间件的效果,如下:
app.get('/formdatas/:formid', authorize.editor, routes.formData.showList);
app.get('/formdatas/create/:formid', authorize.editor, routes.formData.showCreateData);
app.post('/formdatas/create/:formid', writeLog, authorize.editor, routes.formData.createData);
app.get('/formdatas/update/:id', authorize.editor, routes.formData.showUpdateData);
app.post('/formdatas/update/:id', writeLog, authorize.editor, routes.formData.updateData);
app.get('/formdatas/delete/:id', writeLog, authorize.editor, routes.formData.deleteData);
app.get('/formdatas/csv/:formid', writeLog, authorize.editor, routes.formData.getCSV);

ddms(基于 Express 的表单管理系统)源码学习的更多相关文章

  1. spring security 之自定义表单登录源码跟踪

    ​ 上一节我们跟踪了security的默认登录页的源码,可以参考这里:https://www.cnblogs.com/process-h/p/15522267.html 这节我们来看看如何自定义单表认 ...

  2. 基于SSM开发学生信息管理系统源码

    开发环境:    Windows操作系统开发工具: Eclipse+Jdk+Tomcat+MySql数据库 运行效果图 源码及原文链接:https://javadao.xyz/forum.php?mo ...

  3. jquery表单验证源码

    /**数据验证完整性**/$.fn.Validform = function () {    var Validatemsg = "";    var Validateflag = ...

  4. 基于Struts2开发学生信息管理系统 源码

    开发环境:    Windows操作系统开发工具: Eclipse+Jdk+Tomcat+MYSQL数据库 运行效果图: 联系博主-Q:782827013

  5. JS表单验证源码(带错误提示及密码等级)

    先晒图 index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  6. antd4 源码学习 :表单

    Evernote Export 首先.vue 的数据流是双向的,而 react 的数据流是单向的. 这意味着什么? 这意味着,vue 中,子组件可以用 emit 把数据更新传给父组件.而 react ...

  7. Java开源生鲜电商平台-订单表的设计(源码可下载)

    Java开源生鲜电商平台-订单表的设计(源码可下载) 场景分析说明: 买家(餐馆)用户,通过APP进行选菜,放入购物车,然后下单,最终支付的流程,我们称为下单过程. 买家可以在张三家买茄子,李四家买萝 ...

  8. 基于JDK1.8版本的hashmap源码笔记(二)

    这一篇是接着上一篇写的, 上一篇的地址是:基于JDK1.8版本的hashmap源码分析(一)     /**     * 返回boolean类型的值,当集合中包含key的键值,就返回true,否则就返 ...

  9. 基于jdk1.8的HashMap源码学习笔记

    作为一种最为常用的容器,同时也是效率比较高的容器,HashMap当之无愧.所以自己这次jdk源码学习,就从HashMap开始吧,当然水平有限,有不正确的地方,欢迎指正,促进共同学习进步,就是喜欢程序员 ...

随机推荐

  1. 阻塞非阻塞,同步异步四种I/O方式

    举一个去书店买书的例子吧: (同步)阻塞: 你去书店买书,到柜台告诉店员,需要买一本APUE,然后一直在柜台等.(阻塞) 店员拿到书以后交给你. (同步)非阻塞: 你去书店买书,到柜台告诉店员A,需要 ...

  2. javascript判断变量是不是空值

    JavaScript本身没有判断一个变量是不是空值的函数,因为变量有可能是string,object,number,boolean等类型,类型不同,判断方法也不同.所以在文章中写了一个函数,用以判断J ...

  3. Ubuntu下更改网卡名称

    这个方法用于解决Ubuntu下更换网卡后,新网卡变更为eth1,并且源网卡的名称eth0,无法给新网卡用的情况.也可以用于为网卡更名.网 卡MAC地址改变之后,在Linux中找到网卡,新的网卡会被识别 ...

  4. 一个login

    login 1.获取提交表单,保存到变量中.2.判断用户密码是否正确,利用Model类.3.验证用户是否激活.3.判断用户是否记住登录状态,是的话,将其用cookie和session分别保存.没有的话 ...

  5. redis的 rdb 和 aof 持久化的区别 [转]

    aof,rdb是两种 redis持久化的机制.用于crash后,redis的恢复. rdb的特性如下: Code: fork一个进程,遍历hash table,利用copy on write,把整个d ...

  6. 【转载】Java中的回车换行符/n /r /t

    source:http://hane00.blog.163.com/blog/static/1600615220126204446809/ '\r'是回车,'\n'是换行,前者使光标到行首,后者使光标 ...

  7. JS新手易错点

    写给自己 字符串换行不能直接换行,需要在行尾加换行符"\" var a = "aa bb" 是不行的 需要改成 var a="aa\ bb"

  8. extjs6环境

    安装JDK http://www.oracle.com/technetwork/java/javase/downloads/ 安装到指定路径,例如D:\Java配置环境变量 此电脑—属性—高级系统设置 ...

  9. Android adb常用指令

    Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态. 可以通过下列几种方法加入adb: 在设备上运行shell命令 通过端口转发来管理模拟器或设备 从模拟器或 ...

  10. 接口测试总结<转>

    本文主要分为两个部分: 第一部分:主要从问题出发,引入接口测试的相关内容并与前端测试进行简单对比,总结两者之前的区别与联系.但该部分只交代了怎么做和如何做?并没有解释为什么要做? 第二部分:主要介绍为 ...