NodeJS Express app.locals无法在功能中直接访问

时间:2015-07-02 17:02:59

标签: node.js templates express scope ejs

这是一个奇怪的问题,但跟着我。我有一个带快递应用程序的nodejs服务器。在应用程序内部,我将我的本地设置如下:

USE master; 
GO  

CREATE ASYMMETRIC KEY SQLCLRTestKey FROM EXECUTABLE FILE = 'C:\MyDBApp\SQLCLRTest.dll';   
CREATE LOGIN SQLCLRTestLogin FROM ASYMMETRIC KEY SQLCLRTestKey ;  
GRANT UNSAFE ASSEMBLY TO SQLCLRTestLogin ;
GO

ejs呈现为:

CREATE ASSEMBLY SQLCLRTest
FROM 'C:\MyDBApp\SQLCLRTest.dll'
WITH PERMISSION_SET = UNSAFE;

然后,在我的ejs中,我有以下代码:

var moment = require('moment');
app.locals.moment = moment;

有趣的是,那一刻不会引发异常。因此,正如文档所述,它在ejs的范围内定义。但是,ejs提出了一个例外,即在formatDate中没有定义时刻。如果我将formatDate更改为以下内容,一切正常。

exports.page = function (req, res) {
    res.render('first-page');
};

我的问题是ejs中定义的函数是如何定义的,以及应用于哪些上下文。 ejs是否对函数应用不同的上下文而不是浮动javascript?我假设它有类似<% if (!moment) { throw new Error('moment is not defined'); } function formatDate(date) { return moment(date).format(); } %> <p><%= formatDate(1435856054045); %></p>

的东西

1 个答案:

答案 0 :(得分:2)

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不存在(但{正如您已经发现的那样{1}}。

这是问题的一个独立示例:

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>

或者您可以将EJS _with选项设置为moment