142

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

例子

<% if (user) { %>
    <h2><%= user.name %></h2>
<% } %>

这似乎是在检查名为 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)

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

4

16 回答 16

180

就像你对 js 中的任何东西一样typeof foo == 'undefined',或者因为“locals”是包含它们的对象的名称,你可以做if (locals.foo). 这只是原始的js:p

于 2011-03-21T00:22:11.317 回答
40

尝试在变量前面加上locals

例子:if(locals.user){}

于 2017-03-24T07:43:23.667 回答
26
<% if (locals.user) { %>

 // Your logic goes here 

<% } %>
于 2017-09-11T14:08:32.210 回答
14

您可以创建一个检查“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;
}

然后在视图中使用它

<%- get('deep.nested.non.existent.value') %>  //returns: null
<%- get('deep.nested.non.existent.value', "default value") %> //returns: default value
于 2014-01-21T14:33:52.453 回答
12

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

<% if (this.user) { %>
   here, user is defined
<% } %>
于 2014-02-19T14:22:48.883 回答
9

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

if ( typeof users.user_id.name == 'undefined' ) ...

因“无法读取 null 的属性‘名称’”而失败然后我注意到我需要像这样进行检查:

if ( typeof users.user_id == 'undefined' ) ...

我需要检查“名称”的“容器”,所以它起作用了!
之后,这同样有效:

if ( !users.user_id ) ...  

希望能帮助到你。

于 2013-10-17T21:50:34.123 回答
3

来到这个页面寻求答案,但我想出了一个更短的内联语法,它是:

 <h2><%= user.name ? property.escrow.emailAddress : '' %></h2>
于 2018-05-31T23:32:37.983 回答
3

这可能对某人有所帮助。

<p><%= locals?.message %></p>

或者

<p><%= locals.message || '' %></p>
于 2021-04-08T01:01:15.700 回答
2

我所做的只是传递一个我称为 'data' = '' 的默认对象并将其传递给我所有的 ejs 模板。如果您需要将真实数据传递给 ejs 模板,请将它们添加为“数据”对象的属性。

这样,“数据”对象始终被定义,并且您永远不会收到未定义的错误消息,即使“数据”的属性存在于您的 ejs 模板中但不存在于您的节点快速路由中。

于 2016-07-13T13:18:12.660 回答
2

对于您的if声明,您需要使用typeof

<% if (typeof user == 'object' && user) { %>

<% } %>
于 2016-07-19T08:16:02.867 回答
0

我有同样的问题,幸运的是,我发现 JS 中也有一个短路函数(我知道 Ruby 和其他一些语言中有一个)。

在我的服务器/控制器端(来自 Node.js/Express):

return res.render('result', {survey_result : req.session.survey_result&&req.session.survey_result.survey }); 

看看我在那里做了什么?在可能未定义的变量(即request.session.survey_result对象,可能有也可能没有表单数据)之后的 && 是 JS 中的短路符号。如果 && 左边的部分不是未定义的,它所做的只是评估 && 后面的部分。当左侧部分 IS 时,它也不会引发错误undefined。它只是忽略它。

现在,在我的模板中(请记住,我将对象req.session.survey_result_survey对象传递给我的视图survey_result),然后我将字段呈现为:

<table>
    <tr>
        <td> Name:</td>
        <td> <%=survey_result&&survey_result.name%></td>
    </tr>
    <tr>
        <td> Dojo Location:</td>
        <td> <%=survey_result&&survey_result.dojo_loc%></td>
    </tr>
    <tr>
        <td> Favourite Language:</td>
        <td> <%=survey_result&&survey_result.fave_lang%></td>
    </tr>

我在那里也使用了短路,只是为了安全起见。

当我用以前建议的方法尝试它时,只需:

<% if (typeof survey_result !== undefined) { %>
... <!-- some js and/or html code here -->
<% } %>

有时,它仍然会尝试评估 IF 语句中的属性......也许有人可以解释为什么?

另外,我想纠正undefined需要不使用单引号的问题,正如我在前面的示例中看到的那样。因为条件永远不会计算为true,因为您将 String 值'undefined'与数据类型进行比较undefined

于 2018-01-15T22:53:00.680 回答
0

你可以使用这个技巧:

user.name // stops code execution,if user is undefined
(scope.user||0).name // === undefined

其中范围是用户的父对象

于 2019-12-22T18:30:15.803 回答
0

如果你打算经常使用同一个对象,你可以使用这样的函数:

<% function userObj(obj){
    //replace user with what you name your object
    if(typeof user === 'object'){
        let result = user;
        if(obj){
            obj = obj.split('.');
            for(let i = 0; i < obj.length; i++){
                if(obj[i] && obj[i].trim() !== '' && result[obj[i]]){
                    result = result[obj[i]];
                }else{
                    result = false;
                    break;
                }
            }
        }
        return result;
    }
    return false;
} %>

用法:

<% if(userObj('name')){
    <h2><%= userObj('name') %></h2>
} %>
于 2020-01-07T19:55:20.233 回答
0

我想出了另一个解决方案。

<% if(user){ %>
   <% if(user.name){ %>
     <h1><%= user.name %></h1>
<%}}%>

我希望这有帮助。

于 2020-04-25T18:26:34.733 回答
0

对我有用的最安全和唯一的解决方案

<% if (typeof user !== 'undefined' && typeof user.name !== 'undefined') { %>
    <h2><%= user.name %></h2>
<% } %>

或者一个简短的版本

<% (typeof user !== 'undefined' && typeof user.name !== 'undefined') ? user.name : '' %>
于 2022-02-14T10:56:48.840 回答
-2

我在Joe Andrieu 的博客上找到了我认为更好的解决方案:

<%= user.name ? user.name : '' %>

这适用于比其他答案更多的情况(即,当您需要检查单个属性是否存在时)。

于 2021-02-06T05:49:58.637 回答