NodeJS Express app.locals 不能在函数中直接访问
NodeJS Express app.locals are not directly accessible in function
这是一个奇怪的问题,但请跟我来。我有一个带有快速应用程序的 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>
有趣的是那一刻并没有引发异常。因此,正如文档所说,它是在 ejs 的范围内定义的。但是,ejs 引发了一个异常,表示该时刻未在 formatDate 中定义。如果我将 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
块之外; 在 那个块里面,moment
实际上是 locals.moment
,所以你测试它是否存在有效。
但是,当您可以 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();
}
解决这个问题的一种方法是使用函数表达式:
<%
if (typeof moment === 'undefined') {
throw new Error('moment is not defined');
}
var formatDate = function(date) {
return moment(date).format();
};
%>
<p><%= formatDate(1435856054045); %></p>
(它还修复了您的测试以查看 moment
是否实际定义)
或者您可以将 EJS _with
选项设置为 false
。
这是一个奇怪的问题,但请跟我来。我有一个带有快速应用程序的 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>
有趣的是那一刻并没有引发异常。因此,正如文档所说,它是在 ejs 的范围内定义的。但是,ejs 引发了一个异常,表示该时刻未在 formatDate 中定义。如果我将 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
块之外; 在 那个块里面,moment
实际上是 locals.moment
,所以你测试它是否存在有效。
但是,当您可以 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();
}
解决这个问题的一种方法是使用函数表达式:
<%
if (typeof moment === 'undefined') {
throw new Error('moment is not defined');
}
var formatDate = function(date) {
return moment(date).format();
};
%>
<p><%= formatDate(1435856054045); %></p>
(它还修复了您的测试以查看 moment
是否实际定义)
或者您可以将 EJS _with
选项设置为 false
。