2011-03-21 110 views
75

在EJS github上頁,有一個且只有一個簡單的例子: https://github.com/visionmedia/ejs在EJS模板(使用ExpressJS)中檢查變量是否存在的正確方法是什麼?

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

這似乎是檢查一個變量命名用戶的存在,並且如果存在,做一些東西。杜,對嗎?

我的問題是,爲什麼世界上會拋出一個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類型模式。一個不存在的變量的例外對我來說似乎很荒謬。

回答

91

與js,typeof foo == 'undefined'中的任何事情一樣,或者因爲「locals」是包含它們的對象的名稱,您可以執行if (locals.foo)。這只是原始的js:p

+3

我開始懷疑自己手上是否有更大的問題。這也會引發參考錯誤:<%alert('test'); %> – 2011-03-21 00:34:58

+1

@Aashay'alert'是瀏覽器的'window'對象的一部分,並且在node.js中不可用。替代方法是'console.log',但我不知道它是否可以在ejs模板中使用,除非您通過'locals'傳遞它。 – Zikes 2011-03-23 17:10:17

+2

@Zikes在這種情況下,我正在尋找EJS,所以它在瀏覽器頁面上。但是,就像TJ說的那樣,typeof foo =='undefined'起作用。我瞭解到,如果foo已被定義但是爲空或空,我還可以添加一個簡單的!! foo。 – 2011-06-27 06:23:58

5

我在使用mongoose/express/ejs時使用node.js時遇到了同樣的問題,在2個集合與貓鼬的populate()之間建立關係時,在這種情況下,admins.user_id存在但與一個遙不可及的users._id有關。
因此,找不到原因:

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

與失敗「無法讀取的空屬性‘名稱’」 後來我發現,我需要做的檢查是這樣的:

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

我需要檢查「名稱」的「容器」,所以它的工作!
之後,這個工作是相同的:

if (!users.user_id) ... 

希望它能幫助。

+0

爲我的最後一個不工作,我必須使用' typeof'。 – TheBronx 2014-01-05 21:27:33

+0

無論如何,不​​能相信有那麼幾個關於EJS的官方文檔......他們自2010年起不更新他們的[文檔](http://www.embeddedjs.com/)! – aesede 2015-07-20 14:06:58

10

您可以創建檢查 「的obj ===無效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 
+2

不知道爲什麼這是downvoted,它在我看來相當優雅。 – joseym 2015-07-30 15:40:10

10

要檢查用戶是否被定義,你需要做的是:

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

這不適用於最新的EJS庫(1.0.0)。雖然有效的Javascript,EJS將拒絕按預期行事。 – Axoren 2015-02-22 00:45:32

+0

似乎可以在最新的EJS 2.3.4 – Stepan 2015-11-27 09:50:04

+4

中正常工作對我無效。即使我已經定義了'foo',else子句仍然被評估。用EJS 2.3.4測試編輯:使用'locals'代替'this'作品 – 2016-02-09 21:21:22

0

我做的只是傳遞一個默認的對象我稱之爲「數據」 =「」和把它傳遞給我所有的ejs模板。 如果您需要將實際數據傳遞給ejs模板,請將它們添加爲「數據」對象的屬性。

這樣,'data'對象總是被定義的,即使'data'的屬性存在於你的ejs模板中,但你的節點快速路由中不存在未定義的錯誤消息。

1

爲了您if聲明你需要使用typeof

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

<% } %> 
7

嘗試在前面加上變量與locals

例子:if(locals.user){}

5
<% if (locals.user) { %> 

// Your logic goes here 

<% } %> 
0

我有同樣的問題,幸運的是,我發現還有一個短暫的fu JS(我知道Ruby和其他語言中有一個)。

在我的服務器/控制器端(這是從的Node.js /快遞):

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

見我做什麼呢?在可能未定義的變量(即,request.session.survey_result對象,其可能或可能不具有表格數據)之後跟着的是在JS中的短路表示法。它所做的只是評估跟在& &之後的部分,如果沒有定義位於& &左側的部分。當左邊部分是時,它也不會引發錯誤。它只是忽略它。現在

,在我的模板(記住,我傳遞的對象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> 

我用短路也有,只是爲了safe-保持。

當我與先前建議的方法試了一下,只是:

​​

有時,它仍然會嘗試以評估IF語句中的屬性...也許有人可以提供一個解釋,爲什麼?

此外,我想糾正undefined需要沒有單引號,正如我在前面的示例中所看到的。因爲條件永遠不會評估爲true,因爲您正在比較字符串值'undefined'與數據類型undefined

相關問題