nodejs express 框架解密5-视图
本文档是基于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-视图的更多相关文章
- nodejs express 框架解密1-总体结构
本文是基于express3.4.6的. 1.express 代码结构为: bin/express 是在命令行下的生成express 框架目录文件用的 lib/express 是框架的入口文件 lib/ ...
- nodejs express 框架解密3-中间件模块
本文档是基于express 3.4.6 的 在上篇中我们提到了中间件,这篇主要解释这个模块,middleware.js 为: var utils = require('./utils'); /** * ...
- nodejs express 框架解密4-路由
本文档是基于express3.4.6 express 的路由是自己去实现的,没有使用connect中的路由中间件模块. 1.在如何创建一个app那篇中,我们提到了路由, //router //路由 t ...
- nodejs express 框架解密2-如何创建一个app
本文是基于express 3.4.6 的 1.在我们的app.js 文件里面有这么几行 http.createServer(app).listen(app.get('port'), function( ...
- React第一篇: 搭建React + nodejs + express框架
前提: 需要安装Node.js (>6)版本 1.cmd进到本地某个目录, 逐行输入以下指令(以下括号为注释) npm install -g create-react-app (全局安装cr ...
- nodeJS express框架 中文乱码解决办法
最近在研究javascript 的服务端应用 node,之所以想要研究node,是因为前几个月一直在前端挣扎,从javascript入门到在项目中实际使用javascript,确实感悟颇深.javas ...
- NodeJS express框架的使用
首先,可以通过npm或者淘宝镜像cnpm全局安装epress框架,这里不具体说了 npm install -g expressnpm install -g express-generator 新建一个 ...
- nodejs express 框架 上传文件
web 项目应用express4.0框架 html 表单post 文件上传失败,后端无法获取提交文件 express不支持文件上传. 方式一 若是图片,可以将图片转码为BASE64上传 前端框架ang ...
- 安装nodejs express框架时express命令行无效
我也是看了这篇才明白.http://jingyan.baidu.com/article/922554468a3466851648f419.html 最近在看一本书,nodejs开发指南.至于出现这个问 ...
随机推荐
- C# 基本算法
1.冒泡排序 排序 ,,,,,, }; ; i < ArrayList.Count(); i++) { for (int j = i; j < ArrayList.Count(); j++ ...
- C++ set使用
C++ set使用 实际上c++ STL中的set是的实现和C++ STL中的map的实现的底层数据结构是一样的,如果我们不在考虑红黑树中的卫星数据,而只是关键字,那么同样不允许key值得重复,那么就 ...
- MindFusion Pack for ASP.NET发布v2013.R2
在MindFusion.Diagramming for WebForms中: 导入OpenOffice Draw文件 新的DrawImporter类允许你通过OpenOffice Draw Vecto ...
- html 问题
1.footer处理 目标: 页面较短,footer位于页面底部,出现滚动条时,依然在原来的位置,不随滚动条移动 页面较长,位于元素底部 .container{ position: relative ...
- 【概念笔记】JavaEE - web part2
IT`huhui前言录 续JavaEE - web part1 链接http://www.cnblogs.com/ithuhui/p/5930745.html, 持续修改更新. Cookie 1. 定 ...
- 跟我一起学WCF(7)——WCF数据契约与序列化详解
一.引言 在前面博文介绍到,WCF的契约包括操作契约.数据契约.消息契约和错误契约,前面一篇博文已经结束了操作契约的介绍,接下来自然就是介绍数据契约了.所以本文要分享的内容就是数据契约. 二.数据契约 ...
- bootstrap日期选择器-datetimepicker
地址:http://www.bootcss.com/p/bootstrap-datetimepicker/ 使用方法,html: <div class="input-append da ...
- [读书笔记]C#学习笔记六: C#3.0Lambda表达式及Linq解析
前言 最早使用到Lambda表达式是因为一个需求:如果一个数组是:int[] s = new int[]{1,3,5,9,14,16,22};例如只想要这个数组中小于15的元素然后重新组装成一个数组或 ...
- 使用TabBarController(代码实现)
step01:使用Xcode创建一个项目 step02:填写项目必要信息 step03:检查文件结构树是否正确 step04:创建一些类,这些类将会在后面用到!(选择Swift File) step0 ...
- paip.提升性能---mysql 优化cpu多核以及lan性能的关系.
paip.提升性能---mysql 优化cpu多核以及lan性能的关系. 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http:/ ...