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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5372559/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 13:58:10  来源:igfitidea点击:

What is the proper way to check for existence of variable in an EJS template (using ExpressJS)?

node.jsexpressejs

提问by Aashay Desai

On the EJS github page, there is one and only one simple example: https://github.com/visionmedia/ejs

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

Example

例子

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

This seems to be checking for the existence of a variable named user, and if it exists, do some stuff. Duh, right?

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

My question is, why in the world would Node throw a ReferenceError if the user variable doesn't exist? This renders the above example useless. What's the appropriate way to check for the existence of a variable? Am I expected to use a try/catch mechanism and grab that ReferenceError?

我的问题是,如果用户变量不存在,为什么 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)

I understand that I could make this error go away by simply adding a "user" local variable in my server code, but the whole point here is that I want to check for the existence of such variables at runtime using your every day if/else nullcheck type pattern. An exception for a variable that doesn't exist seems ridiculous to me.

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

回答by tjholowaychuk

The same way you would do it with anything in js, typeof foo == 'undefined', or since "locals" is the name of the object containing them, you can do if (locals.foo). It's just raw js :p

与对 js 中的任何内容执行相同的方法typeof foo == 'undefined',或者由于“locals”是包含它们的对象的名称,因此您可以执行if (locals.foo). 这只是原始 js :p

回答by spencer.sm

Try prepending the variable with locals

尝试在变量前面加上 locals

Example: if(locals.user){}

例子: if(locals.user){}

回答by Anirudh

<% if (locals.user) { %>

 // Your logic goes here 

<% } %>

回答by Paulius Uza

You can create a view helper which checks for "obj === void 0", this one is for express.js:

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

Then use it in the view like

然后在视图中使用它

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

回答by HenioJR

To check if user is defined, you need to do that:

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

<% if (this.user) { %>
   here, user is defined
<% } %>

回答by aesede

I've come across the same issue using node.js with mongoose/express/ejs when making a relation between 2 collections together with mongoose's populate(), in this case admins.user_id existed but was related to an inexistant users._id.
So, couldn't find why:

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

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

was failing with "Cannot read property 'name' of null" Then I noticed that I needed to do the checking like this:

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

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

I needed to check the "container" of 'name', so it worked!
After that, this worked the same:

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

if ( !users.user_id ) ...  

Hope it helps.

希望能帮助到你。

回答by Adam Boostani

Came to this page for an answer but I came up with a shorter inline syntax for it which is:

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

 <h2><%= user.name ? property.escrow.emailAddress : '' %></h2>

回答by Fabien Thetis

For your ifstatement you need to use typeof:

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

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

<% } %>

回答by Yekatjarina Aljaksandrayna Shu

I had same issue, and luckily, I found that there is also a short-circuit function in JS (I knew there was one in Ruby and some other languages).

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

On my server/controller side (this is from Node.js/Express):

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

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

See what I did there? The && which follows after a possibly undefined variable (i.e. request.session.survey_resultobject, which might or might not have form data) is the short-circuit notation in JS. What it does is only evaluate the part that follows the && if the part to the left of the && is NOT undefined. It also does not throw an error when the left part IS undefined. It just ignores it.

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

Now, in my template (remember that I passed the object req.session.survey_result_surveyobject to my view as survey_result) and then I rendered fields as:

现在,在我的模板中(请记住,我将对象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>

I used short-circuit there also, just for safe-keeps.

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

When I tried it with previously suggested ways, just:

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

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

Sometimes, it would still try to evaluate the properties within the IF statement...Maybe someone can offer an explanation as to why?

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

Also, I wanted to correct that undefinedneeds to be without the single quotes, as I saw done in previous examples. Because the condition will never evaluate to true, as you are comparing a String value 'undefined'with a datatype undefined.

另外,我想更正undefined需要没有单引号的情况,正如我在前面的示例中看到的那样。因为条件永远不会评估为true,因为您将 String 值'undefined'与数据类型进行比较undefined

回答by Robert Brax

What I do is just pass a default object I call 'data' = '' and pass it to all my ejs templates. If you need to pass real data to ejs template, add them as property of the 'data' object.

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

This way, 'data' object is always defined and you never get undefined error message, even if property of 'data' exist in your ejs template but not in your node express route.

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