NodeJS Express app.locals不能直接在函数中访问
这是一个奇怪的问题,但跟着我。 我有一个具有快速应用程序的nodejs服务器。 在应用程序中,我设置我的本地人如下:
var moment = require('moment'); app.locals.moment = moment;
ejs被呈现为:
exports.page = function (req, res) { res.render('first-page'); };
然后,在我的ejs中,我有以下代码:
<% if (!moment) { throw new Error('moment is not defined'); } function formatDate(date) { return moment(date).format(); } %> <p><%= formatDate(1435856054045); %></p>
发生的有趣之处在于那一刻不会引发exception。 因此,正如文献所说,它在ejs的范围内定义。 然而,ejs说在formatDate没有定义时刻的exception。 如果我将formatDate更改为以下,一切正常。
function formatDate(date) { return locals.moment(date).format(); }
我的问题是ejs中定义的函数是如何确定的,以及哪些上下文适用于它们。 ejs是否将一个不同的上下文应用于浮动JavaScript? 我假设它做了一些像formatDateFunctionPointer.call(ejsScope, ...);
当ejs
输出生成的函数(模板被编译到这个函数)时,问题就变得清晰了:
with (locals || {}) { if (!moment) { throw new Error('moment is not defined'); } function formatDate(date) { return moment(date).format(); } ... }
问题在于你的formatDate
函数被挂到了with
block之外; 在那个块里面 , moment
其实locals.moment
,所以你的testing看看它是否存在着作品。
然而,当你可以formatDate
,它不会在with
块的上下文中运行,因此, moment
不存在(但是locals.moment
的确如你已经发现的那样)。
以下是这个问题的一个独立的例子:
var obj = { test : 123 }; with (obj) { if (test !== 123) throw new Error('test does not equal 123'); function showTest() { console.log('test', test); } showTest(); }
解决这个问题的一种方法是使用函数expression式:
<% if (typeof moment === 'undefined') { throw new Error('moment is not defined'); } var formatDate = function(date) { return moment(date).format(); }; %> <p><%= formatDate(1435856054045); %></p>
(它也修复你的testing,看看是否实际定义的moment
)
或者您可以将EJS _with
选项设置为false
。