Node.js教程之一种Node.js的MVC框架
沉沙 2019-03-11 来源 : 阅读 677 评论 0

摘要:本篇文章探讨了Node.js教程之一种Node.js的MVC框架,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。

本篇文章探讨了Node.js教程之一种Node.js的MVC框架,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。

Node.js教程之一种Node.js的MVC框架

<

 mvc会针对请求进行分发,分发一般有controller(针对模块),action(针对模块中的方法),args(请求的参数)。
1.先对http请求的url进行设置,解析url中的各种参数:
//config.js
var route = require(‘./route‘);
//针对ajax请求route.map({
    method:‘get‘,
    url: /^\/category/mailCategory/i,
    controller: ‘mailCategory‘,
    action: ‘getMailCategory‘
});//controller为空,针对页面,针对页面
route.map({
    method: ‘get‘,
    url: /^\/$/i,
    controller: ‘‘,
    action: ‘list.html‘
});
server.js的入口:
exports.runServer = function(port){
    port = port || 10088;
    /*
      function(req,res){}它将会自动加入到 ‘request‘ 事件的监听队列。
      它是http.IncomingMessage的一个实例。
     */
    var server = http.createServer(function(req, res){
        var _postData = ‘‘;
        //on用于添加一个监听函数到一个特定的事件
        req.on(‘data‘, function(chunk)
        {
            _postData += chunk;
        })
        .on(‘end‘, function()
        {
          req.post = querystring.parse(_postData);
            handlerRequest(req, res);
        });
       
    }).listen(port);   //程序运行的入口 
    console.log(‘Server running at //180.150.189.25:‘+ 10088 +‘/‘);
};
 当接收完请求的URL之后,执行handlerRequest(req, res);
/**
 * 所有请求的统一入口
 */
var handlerRequest = function(req, res){
    //通过route来获取controller和action信息
    var actionInfo = route.getActionInfo(req.url, req.method);
    //如果route中有匹配的action,则分发给对应的action
    if(actionInfo.action){
        var controller = actionInfo.controller;
        //直接跳转页面
        if(controller == ""){
            viewEngine.forward(req, res, actionInfo.action);
            return;
        }
        //加载action
    if(controller[actionInfo.action]){
        var ct = new controllerContext(req, res);
            //如果是post请求,从重新设置参数
            if(req.method.toLowerCase() == "post"){
                actionInfo.args = req.post;
            }
            //通过apply将controller的上下文对象传递给action,路径转化就在这里。
            controller[actionInfo.action].call(ct, actionInfo.args);
        }else{
            handler500(req, res, ‘Error: controller "‘ + actionInfo.controller + ‘" without action "‘ + actionInfo.action + ‘"‘)
        }
    }else{
        //如果route没有匹配到,则当作静态文件处理
        staticFileServer(req, res);
    }
};
viewEngine.forward代码如下:
var staticFileServer = function(req, res, filePath){
    if(!filePath){
        filePath = path.join(__dirname, config.staticFileDir, url.parse(req.url).pathname);
    }
    fs.exists(filePath, function(exists) { 
        if(!exists) { 
            //目录不存在的情况
            handler404(req, res); 
            return; 
        } 
 
        var raw = fs.createReadStream(filePath);     
        var ext = path.extname(filePath);
        ext = ext ? ext.slice(1) : ‘html‘;
        var acceptEncoding = req.headers[‘accept-encoding‘];
        var head = {‘Content-Type‘: contentTypes[ext] || ‘text/html‘};
        if (!acceptEncoding) {
            acceptEncoding = ‘‘;
        }
        //根据请求头部信息,返回相应的数据
       if(acceptEncoding.match(/\bgzip\b/)) {
            head["content-encoding"] = "gzip";
            res.writeHead(200, head);
            raw.pipe(zlib.createGzip()).pipe(res);
        }else if (acceptEncoding.match(/\bdeflate\b/)) {
            head["content-encoding"] = "deflate";
            res.writeHead(200, head);
            raw.pipe(zlib.createDeflate()).pipe(res);
        } else {
            res.writeHead(200, head);
            raw.pipe(res);
        }
 
    });
};
 ct的上下文如下:
//controller的上下文对象
var controllerContext = function(req, res){
    this.req = req;
    this.res = res;
    this.dbPool = dbPool;
    this.contextPath = __dirname;
    this.handler404 = handler404;
    this.handler500 = handler500;
};
2.controller
通过上面的转发就可以把URL与module中的方法映射起来,我们写方法就可以按照模块来写了,例如mailCategory中的getMailCategory的方法如下:
在src模块中的action模块的MailCategory.js中:
/*MailCategory.js,提供两个action 
    getMailList 和 getMailCategory
*/
exports.getMailList = function(args){
    var context = this;
    var result = {errCode: 0, msg: ‘success‘, categoryId: categoryId, data:[]};
   
    //参数校验
    var categoryId = args.categoryId;
    if(!categoryId){
        emitter.emit("invalidCategoryId", result, context);
        return false;
    } 
/**
 * 获取邮件栏目信息
 * @param isList 1 只是返回栏目列表 0 返回栏目及模块信息
 * @returns {errCode:0, msg:‘success‘, data:[{id:‘‘, name: ‘‘, alias: ‘‘},...]}
 * @returns {errCode:0, msg:‘success‘, data: [{id:‘‘, name:‘‘, alias:‘‘, modules:[{id:‘‘, name:‘‘}, ...]}]}
 */
exports.getMailCategory = function(args){
}
3.module
  为controller层提供数据,直接与数据库连接,或者中间加一道缓存,例如redis。刚刚看到在映射的过程中,传递对象的成员
   this.dbPool = dbPool;它的定义如下:
dbManager = require(‘./src/utilities/DbManager‘);
//数据库链接池
var dbPool = dbManager.getPool();
DbManager.js封装了连接数据库,或者一个连接池的对象
//创建mysql数据库链接
var mysql = require(‘mysql‘);
//连接池
var dbConfig = {
    host: ‘180.150.189.25‘,
    port: ‘3306‘,
    user: ‘iyy‘,
    password: ‘iyy@2015‘,
    database: ‘anthony‘,
    connectionLimit: 20       //连接池最大连接数
    //waitForConnections: false
}
//从数据库获取一个链接
exports.getConnection = function(){
    return mysql.createConnection(dbConfig);   
}
exports.getPool = function(){
    var pool = mysql.createPool(dbConfig);
    return pool;
}
这样就可以在controller模块中直接操作数据库,如下:
context.dbPool.getConnection(function(err,connection){
        if(err){
            emitter.emit("connectFailed", result, context);
            return false;
        }
        //可以进一步拆分到module中。
        connection.query("delete from MailModule  where id="+intDeleteId,function(err,res){
            if(err) {
                emitter.emit("queryFailed", result, context);
                return false;
            }
            /*
            emitter.on("success", function(result, context){
                result.errCode = 0;
                result.msg = "success";
                var str=‘updateuserinfo_callback({"ret":2,"errmsg":"asdas"})‘;
                context.renderJson(str);
            });
             */
            emitter.emit("success", result, context);
        });
        //释放链接
        connection.end();
    });
   

本文由职坐标整理发布,学习更多的相关知识,请关注职坐标IT知识库!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程