在EJS模板中检查变量是否存在的正确方法是什么(使用ExpressJS)?

Aas*_*sai 106 ejs node.js express

在EJS github页面上,只有一个简单的例子:https: //github.com/visionmedia/ejs

<% if (user) { %>
    <h2><%= user.name %></h2>
<% } %>
Run Code Online (Sandbox Code Playgroud)

这似乎是检查是否存在名为user的变量,如果存在,则执行一些操作.呃,对吗?

我的问题是,如果用户变量不存在,为什么Node会抛出一个ReferenceError?这使得上面的例子变得毫无用处.检查变量是否存在的合适方法是什么?我是否希望使用try/catch机制并获取ReferenceError?

ReferenceError: user is not defined
    at IncomingMessage.anonymous (eval at <anonymous> (/usr/local/lib/node/.npm/ejs/0.3.1/package/lib/ejs.js:140:12))
    at IncomingMessage.<anonymous> (/usr/local/lib/node/.npm/ejs/0.3.1/package/lib/ejs.js:142:15)
    at Object.render (/usr/local/lib/node/.npm/ejs/0.3.1/package/lib/ejs.js:177:13)
    at ServerResponse.render (/usr/local/lib/node/.npm/express/1.0.7/package/lib/express/view.js:334:22)
    at Object.<anonymous> (/Users/me/Dropbox/Projects/myproject/server.js:188:9)
    at param (/usr/local/lib/node/.npm/connect/0.5.10/package/lib/connect/middleware/router.js:146:21)
    at pass (/usr/local/lib/node/.npm/connect/0.5.10/package/lib/connect/middleware/router.js:162:10)
    at /usr/local/lib/node/.npm/connect/0.5.10/package/lib/connect/middleware/router.js:152:27
    at Object.restrict (/Users/me/Dropbox/Projects/myproject/server.js:94:5)
    at param (/usr/local/lib/node/.npm/connect/0.5.10/package/lib/connect/middleware/router.js:146:21)
Run Code Online (Sandbox Code Playgroud)

我明白我可以通过在我的服务器代码中添加一个"用户"局部变量来消除这个错误,但这里的重点是我想在运行时使用你的每天if/else来检查这些变量是否存在nullcheck类型模式.不存在的变量的例外对我来说似乎很荒谬.

tjh*_*huk 132

与js中的任何内容相同typeof foo == 'undefined',或者因为"locals"是包含它们的对象的名称,您可以这样做if (locals.foo).这只是原始的js:p

  • 这有简写吗?为什么EJS不尊重if(foo)案件? (18认同)
  • `if(locals.user){}`FTW (4认同)
  • 我开始怀疑自己手上是否有更大的问题.这也会引发参考错误:<%alert('test'); %> (3认同)
  • @Aashay `alert` 是浏览器的 `window` 对象的一部分,在 Node.js 中不可用。另一种选择是“console.log”,尽管我不知道它是否在 ejs 模板中可用,除非您通过“locals”传递它。 (2认同)
  • @Zikes在这种情况下,我正在专门寻找EJS,所以它在浏览器页面上.但是,就像TJ所说,typeof foo =='undefined'有效.我了解到如果定义了foo,我也可以添加一个简单的!! foo但是为null或为空. (2认同)

spe*_*.sm 22

尝试使用前置变量 locals

例: if(locals.user){}

  • 这应该是正确的答案 (2认同)

Ani*_*udh 16

<% if (locals.user) { %>

 // Your logic goes here 

<% } %>
Run Code Online (Sandbox Code Playgroud)


Hen*_*oJR 12

要检查用户是否已定义,您需要这样做:

<% if (this.user) { %>
   here, user is defined
<% } %>
Run Code Online (Sandbox Code Playgroud)

  • 对我不起作用.即使我已经定义了`foo`,仍然会评估else子句.用EJS 2.3.4 EDIT测试:使用`locals`代替`this`有效 (5认同)
  • 这在最新的EJS库(1.0.0)中不起作用.虽然有效的Javascript,EJS将拒绝按预期行事. (3认同)

Pau*_*Uza 11

您可以创建一个查看"obj === void 0"的视图助手,这个用于express.js:

res.locals.get = function() {
    var args = Array.prototype.slice.call(arguments, 0);
    var path = args[0].split('.');
    var root = this;
    for (var i = 0; i < path.length; i++) {
        if(root[path[i]] === void 0) {
            return args[1]?args[1]:null;
        } else {
            root = root[path[i]];
        }
    };
    return root;
}
Run Code Online (Sandbox Code Playgroud)

然后在视图中使用它

<%- get('deep.nested.non.existent.value') %>  //returns: null
<%- get('deep.nested.non.existent.value', "default value") %> //returns: default value
Run Code Online (Sandbox Code Playgroud)

  • 不知道为什么这个被投票,我认为它相当优雅. (2认同)
  • @NobleUplift 根据[文档](https://ejs.co/#docs),在“标签”下: `&lt;%=` HTML 首先对值进行转义;`&lt;%-` 输出未转义的值。因此,当使用“&lt;%-”时,“&lt;b&gt;”将成为粗体标记,而当使用“&lt;%=”时,则只是文本“&lt;b&gt;” (2认同)

aes*_*ede 5

在使用mongoose的populate()创建2个集合之间的关系时,我遇到了使用node.js和mongoose/express/ejs的相同问题,在这种情况下,admins.user_id存在但与不相关的users._id相关.
所以,找不到原因:

if ( typeof users.user_id.name == 'undefined' ) ...
Run Code Online (Sandbox Code Playgroud)

失败了"无法读取属性'名称'为null"然后我注意到我需要像这样进行检查:

if ( typeof users.user_id == 'undefined' ) ...
Run Code Online (Sandbox Code Playgroud)

我需要检查"名称"的"容器",所以它有效!
在那之后,这也是一样的:

if ( !users.user_id ) ...  
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.