zoukankan      html  css  js  c++  java
  • 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);

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

  • 相关阅读:
    hdu 5366 简单递推
    hdu 5365 判断正方形
    hdu 3635 并查集
    hdu 4497 数论
    hdu5419 Victor and Toys
    hdu5426 Rikka with Game
    poj2074 Line of Sight
    hdu5425 Rikka with Tree II
    hdu5424 Rikka with Graph II
    poj1009 Edge Detection
  • 原文地址:https://www.cnblogs.com/yupeng/p/3482360.html
Copyright © 2011-2022 走看看