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. libxml2 移植 arm9

    准备工作: 1.libxml2软件版本:libxml2-2.6.32.tar.gz 2.交叉编译工具链:arm-none-linux-guneabi 软件安装: 1.设置环境变量: export PA ...

  2. NC nc5.x报表设置合计行是否显示

    首先要先继承UI类 /** * 设置合计行是否显示 */ public TotalsReportUI() { super(); getReportBase().getBodyPanel().setTo ...

  3. ASP.NET MVC3 Model验证总结

    ASP.NET MVC3中的Model是自验证的,这是通过.NET4的System.ComponentModel.DataAnnotations命名空间完成的. 我们要做的只是给Model类的各属性加 ...

  4. 对于cookie和session的形象解释

    生活中的场景: 一群人,买豆浆,也不排队,乱哄哄的 豆浆现磨. 先交钱,交完钱蹲在一边等. 这个老板非常健忘! 记忆时间:转脸就忘. 李四给老板钱<--->"大杯黄豆!" ...

  5. linux环境搭建

    gcc编译安装 解压下载的gcc包:tar -xxx gcc-xxxx.xxx.xx 下载安装gcc依赖库:./contrib/download_prerequisites configure一个Ma ...

  6. 强大的Spring缓存技术(下)

    基本原理 一句话介绍就是Spring AOP的动态代理技术. 如果读者对Spring AOP不熟悉的话,可以去看看官方文档 扩展性 直到现在,我们已经学会了如何使用开箱即用的 spring cache ...

  7. nginx编译模块详解

    –prefix= 指向安装目录–sbin-path 指向(执行)程序文件(nginx)–conf-path= 指向配置文件(nginx.conf)–error-log-path= 指向错误日志目录–p ...

  8. 关于C++的递归(以汉诺塔为例)

    关于C++,hanoi塔的递归问题一直是个经典问题,我们学习数据结构的时候也会时常用到, 因为它的时间复杂度和空间复杂度都很高,我们在实际的应用中不推荐使用这种算法,移动n个盘子, 需要2的n次幂减一 ...

  9. HTML 判断手机的类型(苹果手机安卓手机)

    function isJudege_PlatForm() { var version = navigator.appVersion; var platName = navigator.userAgen ...

  10. 父窗口,子窗口之间的JS"通信"方法

    今天需要在iframe内做一个弹窗,但使用弹窗组件的为子窗口,所以弹窗只在子窗口中显示掩膜层和定位,这样不符合需求. 后来晓勇哥指点,了解到一个以前一直没关注到的东西,每个窗口的全局变量,其实都存在对 ...