當咱們使用 Express 作服務端框架的時候,若是選擇一種相似於 EJS這種模板引擎渲染前端頁面的時候,常常服務端在響應 http 請求的時候調用 res.render({options})
去向模板中渲染數據。前端
咱們還會常常看到 res.locals 和 app.locals 這對象,那麼他們究竟是幹什麼的呢? 查看原代碼:web
//express/lib/response.js res.render = function render(view, options, callback) { var app = this.req.app; var done = callback; var opts = options || {}; var req = this.req; var self = this; // support callback function as second arg if (typeof options === 'function') { done = options; opts = {}; } // merge res.locals opts._locals = self.locals; // default callback to respond done = done || function (err, str) { if (err) return req.next(err); self.send(str); }; // render app.render(view, opts, done); };
變量 opts 初始時得到開發人員代碼中傳入的 options 對象,這段代碼中的opts._locals = self.locals;
self 指向 res 對象自身,即又在最終渲染到模板中的變量裏面增添了一個對象屬性,該屬性的值爲 res.locals
express
緊接着調用到了 app.render
函數,並傳入 opts 對象。npm
//express/lib/application.js app.render = function render(name, options, callback) { var cache = this.cache; var done = callback; var engines = this.engines; var opts = options; var renderOptions = {}; var view; // support callback function as second arg if (typeof options === 'function') { done = options; opts = {}; } // merge app.locals merge(renderOptions, this.locals); // merge options._locals if (opts._locals) { merge(renderOptions, opts._locals); } // merge options merge(renderOptions, opts); // set .cache unless explicitly provided if (renderOptions.cache == null) { renderOptions.cache = this.enabled('view cache'); } // primed cache if (renderOptions.cache) { view = cache[name]; } // view if (!view) { var View = this.get('view'); view = new View(name, { defaultEngine: this.get('view engine'), root: this.get('views'), engines: engines }); if (!view.path) { var dirs = Array.isArray(view.root) && view.root.length > 1 ? 'directories "' + view.root.slice(0, -1).join('", "') + '" or "' + view.root[view.root.length - 1] + '"' : 'directory "' + view.root + '"' var err = new Error('Failed to lookup view "' + name + '" in views ' + dirs); err.view = view; return done(err); } // prime the cache if (renderOptions.cache) { cache[name] = view; } } // render tryRender(view, renderOptions, done);
merge是一個很方便合併兩個對象的第三方模塊。app
不難看出 這函數在得出最終的渲染變量對象的時候又再一次 merge了app.locals對象,將開發人員 res.render 傳入的對象,res.locals 對象,app.locals 對象三者合併做爲最終渲染模板的素材。框架
知道這個過程以後,很容易就能理解爲何常常在項目入口文件 app.js 中常常看到以下代碼:less
// 設置站點全局常量 app.locals.webGlobal = { title: "", description: "", keywords: "" } // 設置可變可是又是每一個模板老是須要的一些模板變量 app.use(function(req, res, next) { res.locals._host = req.headers.host; res.locals._user = req.user; res.locals._url = req.url || req.originalUrl; res.locals._moment = moment; res.locals._enums = enums; next(); });
res.render 傳入的對象做爲特定場景特定頁面的個性化變量信息數據,app.locals
上一般掛載常量信息,res.locals
上一般掛載變量信息,三者相輔相成的共同構成渲染模板的整個變量信息。ide