本文档是基于express 3.4.6 的

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

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

这个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方法

  1. res.render = function(view, options, fn){
  2. var self = this
  3. , options = options || {}
  4. , req = this.req
  5. , app = req.app;
  6.  
  7. // support callback function as second arg
  8. if ('function' == typeof options) {
  9. fn = options, options = {};
  10. }
  11.  
  12. // merge res.locals
  13. options._locals = self.locals;
  14.  
  15. // default callback to respond
  16. fn = fn || function(err, str){
  17. if (err) return req.next(err);
  18. self.send(str);
  19. };
  20.  
  21. // render
  22. app.render(view, options, fn);
  23. };

可以看到:

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

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

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

  1. app.render = function(name, options, fn){
  2. var opts = {}
  3. , cache = this.cache
  4. , engines = this.engines
  5. , view;
  6.  
  7. // support callback function as second arg
  8. if ('function' == typeof options) {
  9. fn = options, options = {};
  10. }
  11.  
  12. // merge app.locals
  13. utils.merge(opts, this.locals);
  14.  
  15. // merge options._locals
  16. if (options._locals) utils.merge(opts, options._locals);
  17.  
  18. // merge options
  19. utils.merge(opts, options);
  20.  
  21. // set .cache unless explicitly provided
  22. opts.cache = null == opts.cache
  23. ? this.enabled('view cache')
  24. : opts.cache;
  25.  
  26. // primed cache
  27. if (opts.cache) view = cache[name];
  28.  
  29. // view
  30. if (!view) {
  31. view = new (this.get('view'))(name, {
  32. defaultEngine: this.get('view engine'),
  33. root: this.get('views'),
  34. engines: engines
  35. });
  36.  
  37. if (!view.path) {
  38. var err = new Error('Failed to lookup view "' + name + '"');
  39. err.view = view;
  40. return fn(err);
  41. }
  42.  
  43. // prime the cache
  44. if (opts.cache) cache[name] = view;
  45. }
  46.  
  47. // render
  48. try {
  49. view.render(opts, fn);
  50. } catch (err) {
  51. fn(err);
  52. }
  53. };

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

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

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

视图的这个方法是:

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

引擎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. asp.net写验证码

    生成验证码与匹配验证码的服务端代码 <%@ WebHandler Language="C#" Class="ValidataeCodeHandler" % ...

  2. 解析posix与perl标准的正则表达式区别

    解析posix与perl标准的正则表达式区别 作者: 字体:[增加 减小] 类型:转载 本篇文章是对posix与perl标准的正则表达式区别进行了详细的分析介绍,需要的朋友参考下 正则表达式(Regu ...

  3. Xamarin开发Android笔记:TextView行间距设定

    TextView 在使用TextView的时候会遇到调整行间距的问题,可通过Layout文件添加属性完成,具体属性如下: //设置行间距,如”3dp”. android:lineSpacingExtr ...

  4. 【ASP.NET Web API教程】6.4 模型验证

    本文是Web API系列教程的第6.4小节 6.4 Model Validation 6.4 模型验证 摘自:http://www.asp.net/web-api/overview/formats-a ...

  5. Windows Phone编程中Dispatcher.BeginInvoke的使用

    在学习Windows Phone 程序开发时经常会使用到Dispatcher.BeginInvoke()的编程方法,可能许多初学者并不熟悉Dispatcher.BeginInvoke的使用方法以及为什 ...

  6. AJAX跨域调用相关知识-CORS和JSONP(引)

    AJAX跨域调用相关知识-CORS和JSONP 1.什么是跨域 跨域问题产生的原因,是由于浏览器的安全机制,JS只能访问与所在页面同一个域(相同协议.域名.端口)的内容. 但是我们项目开发过程中,经常 ...

  7. SQL Server 性能优化之——T-SQL NOT IN 和 NOT Exists

    这次介绍一下T-SQL中“Not IN” 和“Not Exists”的优化. Not IN 和 Not Exists 命令 : 有些情况下,需要select/update/delete 操作孤立数据. ...

  8. php性能分析工具 - xhprof的安装使用

    一.前言 有用的东西还是记录下来吧,也方便以后的查询:这次记录一下xhprof的安装使用: xhprof是facebook开源出来的一个php轻量级的性能分析工具,跟Xdebug类似,但性能开销更低, ...

  9. 自制一个能显示helloworld的最简单OS

    <自己动手写操作系统> org 07c00h mov ax,cs mov ds,ax mov es,ax call DispStr jmp $ DispStr: mov ax,BootMe ...

  10. CentOS下搭建NFS服务器总结

    环境介绍: . 服务器: 192.168.0.100 . 客户机: 192.168.0.101 安装软件包: . 服务器和客户机都要安装nfs 和 rpcbind 软件包: yum -y instal ...