【问题标题】:NodeJS Express app.locals are not directly accessible in functionNodeJS Express app.locals 不能在函数中直接访问
【发布时间】:2015-09-20 08:08:03
【问题描述】:

这是一个奇怪的问题,但请跟我来。我有一个带有 express 应用程序的 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, ...);

【问题讨论】:

    标签: node.js templates express scope ejs


    【解决方案1】:

    当您让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

    【讨论】:

    • 很好,谢谢。说得通。发布的代码只是我真实代码的简化,但您将重要部分说得很清楚!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-03
    • 2014-04-03
    • 1970-01-01
    • 2012-12-02
    • 1970-01-01
    • 2019-10-07
    • 2011-03-22
    相关资源
    最近更新 更多