本文档是基于express 3.4.6 的

在我们的代码中,渲染模板大致是这样写的

exports.index = function(req, res){
res.render('index', { title: 'Express' });
};

这个req,res 函数其实是经过了中间件middleware.js 处理后的,我们在前面提到过。

req,res的原型分别为 app.request 和app.response

req.__proto__ = app.request;
res.__proto__ = app.response;

而 app.request 和app.response,本身也是具有app的属性的。

//设置app 的request对象的原型为req,本身的属性为connect对象
app.request = { __proto__: req, app: app };
//设置app的response对象原型为res ,本身的属性为connect对象
app.response = { __proto__: res, app: app };

注意这里的这个app属性

打开response.js 文件,我们看看res.render方法

res.render = function(view, options, fn){
var self = this
, options = options || {}
, req = this.req
, app = req.app; // support callback function as second arg
if ('function' == typeof options) {
fn = options, options = {};
} // merge res.locals
options._locals = self.locals; // default callback to respond
fn = fn || function(err, str){
if (err) return req.next(err);
self.send(str);
}; // render
app.render(view, options, fn);
};

可以看到:

, req = this.req
, app = req.app;

这里的 req = this.req,其实是中间件 里面的  res.req = req;

第二句直接将app带进来了,最后我们执行了app.render方法,它调用了application.js 中得这个方法:

app.render = function(name, options, fn){
var opts = {}
, cache = this.cache
, engines = this.engines
, view; // support callback function as second arg
if ('function' == typeof options) {
fn = options, options = {};
} // merge app.locals
utils.merge(opts, this.locals); // merge options._locals
if (options._locals) utils.merge(opts, options._locals); // merge options
utils.merge(opts, options); // set .cache unless explicitly provided
opts.cache = null == opts.cache
? this.enabled('view cache')
: opts.cache; // primed cache
if (opts.cache) view = cache[name]; // view
if (!view) {
view = new (this.get('view'))(name, {
defaultEngine: this.get('view engine'),
root: this.get('views'),
engines: engines
}); if (!view.path) {
var err = new Error('Failed to lookup view "' + name + '"');
err.view = view;
return fn(err);
} // prime the cache
if (opts.cache) cache[name] = view;
} // render
try {
view.render(opts, fn);
} catch (err) {
fn(err);
}
};

可以看到它调用了视图类:

 view = new (this.get('view'))(name, {
defaultEngine: this.get('view engine'),
root: this.get('views'),
engines: engines
});

最后调用了视图的render方法。 view.render(opts, fn);

视图的这个方法是:

View.prototype.render = function(options, fn){
this.engine(this.path, options, fn);
};
function View(name, options) {
options = options || {};
this.name = name;
this.root = options.root;
var engines = options.engines;
this.defaultEngine = options.defaultEngine;
var ext = this.ext = extname(name);
if (!ext && !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
this.path = this.lookup(name);
}

引擎require了一个方法

this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);

后面就去调用具体的模板引擎了。

nodejs express 框架解密5-视图的更多相关文章

  1. nodejs express 框架解密1-总体结构

    本文是基于express3.4.6的. 1.express 代码结构为: bin/express 是在命令行下的生成express 框架目录文件用的 lib/express 是框架的入口文件 lib/ ...

  2. nodejs express 框架解密3-中间件模块

    本文档是基于express 3.4.6 的 在上篇中我们提到了中间件,这篇主要解释这个模块,middleware.js 为: var utils = require('./utils'); /** * ...

  3. nodejs express 框架解密4-路由

    本文档是基于express3.4.6 express 的路由是自己去实现的,没有使用connect中的路由中间件模块. 1.在如何创建一个app那篇中,我们提到了路由, //router //路由 t ...

  4. nodejs express 框架解密2-如何创建一个app

    本文是基于express 3.4.6 的 1.在我们的app.js 文件里面有这么几行 http.createServer(app).listen(app.get('port'), function( ...

  5. React第一篇: 搭建React + nodejs + express框架

    前提: 需要安装Node.js (>6)版本 1.cmd进到本地某个目录, 逐行输入以下指令(以下括号为注释) npm install -g create-react-app   (全局安装cr ...

  6. nodeJS express框架 中文乱码解决办法

    最近在研究javascript 的服务端应用 node,之所以想要研究node,是因为前几个月一直在前端挣扎,从javascript入门到在项目中实际使用javascript,确实感悟颇深.javas ...

  7. NodeJS express框架的使用

    首先,可以通过npm或者淘宝镜像cnpm全局安装epress框架,这里不具体说了 npm install -g expressnpm install -g express-generator 新建一个 ...

  8. nodejs express 框架 上传文件

    web 项目应用express4.0框架 html 表单post 文件上传失败,后端无法获取提交文件 express不支持文件上传. 方式一 若是图片,可以将图片转码为BASE64上传 前端框架ang ...

  9. 安装nodejs express框架时express命令行无效

    我也是看了这篇才明白.http://jingyan.baidu.com/article/922554468a3466851648f419.html 最近在看一本书,nodejs开发指南.至于出现这个问 ...

随机推荐

  1. com.alibaba.fastjson.JSONObject学习

    JSONObject json = new JSONObject(); //设置json属性,可以是对象,数值 json.put("key",value); //获取json的普通 ...

  2. .NET调用window串口读取电子秤的数据

    Private serialPort As SerialPort  '定义 Public Function CreateSerialPort() As String        Dim strWei ...

  3. FME规划数据GIS更新入库

    规划数据经过转换处理入库GIS,城市规划的特殊性,使得GIS里面数据经过分析处理后直接导出为CAD数据的话,肯定难以满足原来规划的要求,这个是硬伤.又要用GIS来进行空间分析处理统计,数据管理就必须了 ...

  4. 2015年8月17日,杨学明老师《产业互联网化下的研发模式转型》在中国科学院下属机构CNNIC成功举办!

    2015年8月17日,杨学明老师为中国网络新闻办公室直属央企中国互联网络中心(CNNIC)提供了一天的<产业互联网化下的研发模式转型>内训课程.杨学明老师分别从产业互联网化的问题与挑战.传 ...

  5. Android开发学习总结——Android开发的一些相关概念

    一.什么是3G.4G 1995年问世的第一代模拟制式手机(1G)只能进行语音通话. 1996到1997年出现的第二代GSM.CDMA等数字制式手机(2G)便增加了接收数据的功能 Ÿ 3G指的是第三代移 ...

  6. Server Develop (七) Linux 守护进程

    守护进程 守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常常在系统引导装 ...

  7. C语言宏高级用法 [总结]

    1.前言  今天看代码时候,遇到一些宏,之前没有见过,感觉挺新鲜.如是上网google一下,顺便总结一下,方便以后学习和运用.C语言程序中广泛的使用宏定义,采用关键字define进行定义,宏只是一种简 ...

  8. [游戏模版8] Win32 透明贴图

    >_<:The same with previous introduction. In the InitInstance fanction make a little change: &g ...

  9. 清爽绿色格调图文box通用样式

    今天是端午节,小菜献上一款剽窃的box样式,祝大家端午快乐! 此box样式以绿色为主要色调,清新自然,适合大多数设计场景. 此box算是比较高级的了,box中的列表是图文列表,可以显示一张小图片,然后 ...

  10. H5 Canvas刮刮乐

    玩游戏的人 很多时候都会遇到翻牌子  开宝箱. 总有人傻傻的在哪里还纠结很久到底点哪一个! 纠结  指不定翻哪一个会多一点,你明明看到那个卡片的奖项多 . 那我就告诉你好了  其实很多时候在你点开那个 ...