EJS 템플릿 (ExpressJS 사용)에서 변수의 존재를 확인하는 적절한 방법은 무엇입니까?


121

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 유형 패턴. 존재하지 않는 변수에 대한 예외는 저에게 우스꽝스러워 보입니다.

답변:


149

js, typeof foo == 'undefined'또는 "locals"가 그것들을 포함하는 객체의 이름이기 때문에 당신은 할 수 있습니다 if (locals.foo). 그것은 원시 js입니다 : p


3
나는 내 손에 더 큰 문제가 있는지 궁금해하기 시작했다. 이 경우에도 참조 오류가 발생합니다. <% alert ( 'test'); %>
Aashay Desai 2011

1
@Aashay alert는 브라우저 window개체 의 일부이며 node.js에서 사용할 수 없습니다. 대안은 console.log이지만을 통해 전달하지 않는 한 ejs 템플릿에서 사용할 수 있는지 모르겠습니다 locals.
Zikes 2011 년

2
@Zikes이 경우에는 특별히 EJS를 찾고 있으므로 브라우저 페이지에 있습니다. 그러나 TJ가 말했듯이 typeof foo == 'undefined'가 작동합니다. foo가 정의되었지만 null이거나 비어 있으면 간단한 !! foo도 추가 할 수 있다는 것을 배웠습니다.
Aashay 데 사이

21
이것에 대한 속기가 있습니까? EJS가 단순히 if (foo) 사례를 존중하지 않는 이유는 무엇입니까?
mattdlockyer

5
if (locals.user){ }FTW
s2t2



13

"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

3
왜 이것이 반대표를 받았는지 모르겠습니다. 제 생각에는 다소 우아합니다.
joseym

<%=과 의 차이점은 무엇입니까 <%-?
NobleUplift

2
@NobleUplift 문서 에 따라 "태그"아래 : <%=HTML이 값을 먼저 이스케이프합니다. <%-이스케이프되지 않은 값을 출력합니다. 그래서 <b>사용할 때 굵은 태그가 될 것입니다 <%-,하지만 단순히 텍스트 "의 <b>"은 사용하는 경우<%=
마테우스 Avellar

감사합니다! 나는 <%-가 유효한 태그인지 전혀 몰랐다.
NobleUplift

13

사용자가 정의되었는지 확인하려면 다음을 수행해야합니다.

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

3
이것은 최신 EJS 라이브러리 (1.0.0)에서는 작동하지 않습니다. 유효한 Javascript이지만 EJS는 예상대로 작동하지 않습니다.
Axoren 2015

5
나를 위해 작동하지 않습니다. 정의했지만 fooelse 절은 여전히 ​​평가됩니다. EJS 2.3.4로 테스트 됨 편집 : 작업 locals대신 사용this
X_Trust

8

mongoose의 populate ()와 함께 2 개의 컬렉션 사이에 관계를 만들 때 mongoose / express / ejs와 함께 node.js를 사용하는 동일한 문제가 발생했습니다.이 경우 admins.user_id가 존재했지만 존재하지 않는 users._id와 관련이있었습니다.
따라서 이유를 찾을 수 없습니다.

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

"null의 속성 '이름'을 읽을 수 없습니다"로 실패했습니다. 그런 다음 다음과 같은 검사를 수행해야한다는 것을 알았습니다.

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

'이름'의 '컨테이너'를 확인해야해서 작동했습니다!
그 후 이것은 동일하게 작동했습니다.

if ( !users.user_id ) ...  

도움이 되었기를 바랍니다.


어쨌든, EJS에 대한 공식 문서가 거의 없다는 것을 믿을 수 없습니다 ... 그들은 2010 년 이후로 문서를 업데이트하지 않습니다 !!!
aesede

3

대답을 위해이 페이지에 왔지만 다음과 같은 더 짧은 인라인 구문을 생각해 냈습니다.

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

1
'user'개체에 'name'속성이 없으면 ejs 렌더링이 실패하므로 사용하기가 위험합니다.
Marko Rochevski

1

당신을 위해 if문 당신은 사용할 필요가 typeof:

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

<% } %>

0

내가하는 일은 'data'=``라고 부르는 기본 객체를 전달하고 모든 ejs 템플릿에 전달하는 것입니다. 실제 데이터를 ejs 템플릿에 전달해야하는 경우 'data'개체의 속성으로 추가합니다.

이렇게하면 '데이터'개체가 항상 정의되고 '데이터'속성이 ejs 템플릿에 있지만 노드 익스프레스 경로에는없는 경우에도 정의되지 않은 오류 메시지가 표시되지 않습니다.


0

나는 같은 문제가 있었고 운 좋게도 JS에도 단락 기능이 있다는 것을 발견했습니다 (루비와 다른 언어에 하나가 있다는 것을 알고있었습니다).

내 서버 / 컨트롤러 측 (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이전 예제에서 보았 듯이 작은 따옴표없이 수정하고 싶었습니다 . trueString 값 'undefined'을 데이터 유형과 비교할 때 조건이로 평가되지 않기 때문 undefined입니다.


0

이 트릭을 사용할 수 있습니다.

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

여기서 범위는 사용자의 상위 개체입니다.


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>
} %>

0

나는 또 다른 해결책을 생각해 냈습니다.

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

이게 도움이 되길 바란다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.