Bir EJS şablonundaki değişkenin varlığını kontrol etmenin uygun yolu nedir (ExpressJS kullanarak)?


121

EJS github sayfasında tek ve basit bir örnek var: https://github.com/visionmedia/ejs

Misal

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

Bu, user adlı bir değişkenin varlığını kontrol ediyor gibi görünüyor ve eğer varsa, bazı şeyler yapın. Değil mi?

Sorum şu, eğer kullanıcı değişkeni yoksa Node neden dünyada bir ReferenceError atsın? Bu, yukarıdaki örneği işe yaramaz hale getirir. Bir değişkenin varlığını kontrol etmenin uygun yolu nedir? Bir dene / yakala mekanizması kullanıp bu ReferenceError'ı yakalamam bekleniyor mu?

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)

Sunucu koduma sadece bir "kullanıcı" yerel değişkeni ekleyerek bu hatayı ortadan kaldırabileceğimi anlıyorum, ancak buradaki asıl mesele şu ki, if / else nullcheck türü desen. Var olmayan bir değişkenin istisnası bana gülünç geliyor.

Yanıtlar:


149

Tıpkı js'deki herhangi bir şeyle yaptığınız gibi typeof foo == 'undefined'veya "yereller" onları içeren nesnenin adı olduğundan, yapabilirsiniz if (locals.foo). Bu sadece ham js: p


3
Ellerimde daha büyük bir sorun olup olmadığını merak etmeye başlıyorum. Bu da bir Referans Hatası atar: <% alert ('test'); %>
Aashay Desai

1
@Aashay alert, tarayıcının windownesnesinin bir parçasıdır ve node.js'de mevcut değildir. Alternatif olarak console.log, siz onu iletmedikçe bir ejs şablonunda mevcut olup olmadığını bilmiyorum locals.
Zikes

2
@Zikes Bu durumda özellikle EJS'yi arıyorum, bu yüzden tarayıcı sayfasında. Ancak, TJ'nin dediği gibi, typeof foo == 'tanımsız' çalışır. Foo tanımlanmışsa, ancak null veya boşsa basit bir !! foo ekleyebileceğimi öğrendim.
Aashay Desai

21
Bunun için bir kısaltma var mı? EJS neden if (foo) davasını kabul etmiyor?
mattdlockyer

5
if (locals.user){ }FTW
s2t2

26

Değişkeni başına eklemeyi deneyin locals

Misal: if(locals.user){}


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

 // Your logic goes here 

<% } %>

13

"Obj === void 0" için kontrol eden bir görünüm yardımcısı oluşturabilirsiniz, bu, express.js içindir:

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

Sonra görünümde şu şekilde kullanın

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

3
Bunun neden olumsuz oy verildiğinden emin değilim, bence oldukça zarif.
joseym

Arasındaki fark nedir <%=ve <%-?
NobleUplift

2
@NobleUplift Belgelere göre , "Etiketler" altında: <%=HTML önce değerden kaçar; <%-çıkış karaktersiz değeri verir. Yani <b>kullanırken cesur bir etiket olacak <%-, ama sadece metin "<b>" kullanılırken<%=
Matheus Avellar

Teşekkür ederim! Hiçbir fikrim yoktu <% - geçerli bir etiket bile.
NobleUplift

13

Kullanıcının tanımlı olup olmadığını kontrol etmek için bunu yapmanız gerekir:

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

3
Bu, en güncel EJS kitaplığında (1.0.0) çalışmaz. Geçerli bir Javascript olmasına rağmen, EJS beklendiği gibi davranmayı reddedecektir.
Axoren

5
Benim için çalışmıyor. Tanımlamış olsam da foo, else cümlesi hala değerlendirilmektedir. EJS 2.3.4 EDIT ile test edildi: işlerin localsyerine kullanmathis
X_Trust

8

Mongoose'un populate () ile birlikte 2 koleksiyon arasında ilişki kurarken mongoose / express / ejs ile node.js kullanarak aynı sorunla karşılaştım, bu durumda admins.user_id vardı ama inexistant users._id ile ilgiliydi.
Yani neden bulamadım:

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

"Boş değerin 'adı' özelliği okunamıyor" ile başarısız oluyordu. Ardından, şu şekilde kontrol yapmam gerektiğini fark ettim:

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

"Ad" ın "kapsayıcısını" kontrol etmem gerekiyordu, bu yüzden işe yaradı!
Bundan sonra, bu aynı şekilde çalıştı:

if ( !users.user_id ) ...  

Umarım yardımcı olur.


Her neyse, EJS'de bu kadar az resmi belge olduğuna inanamıyorum ... 2010'dan beri belgelerini güncellemiyorlar !!!
aesede

3

Bir cevap için bu sayfaya geldim ancak bunun için daha kısa bir satır içi sözdizimi buldum:

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

1
Bunun kullanılması tehlikelidir, çünkü 'kullanıcı' nesnesinin 'ad' özelliği yoksa, ejs oluşturma başarısız olacaktır.
Marko Rochevski

1

Senin için ifaçıklamaya size kullanımına gerek typeof:

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

<% } %>

0

Yaptığım şey, 'data' = '' adını verdiğim varsayılan bir nesneyi ve onu tüm ejs şablonlarıma iletmek. Gerçek verileri ejs şablonuna iletmeniz gerekiyorsa, bunları 'veri' nesnesinin özelliği olarak ekleyin.

Bu şekilde, 'veri' nesnesi her zaman tanımlanır ve ejs şablonunuzda 'veri' özelliği bulunsa, ancak düğüm ekspres rotanızda olmasa bile hiçbir zaman tanımsız hata mesajı almazsınız.


0

Aynı sorunu yaşadım ve şans eseri, JS'de de bir kısa devre işlevi olduğunu buldum (Ruby'de ve diğer bazı dillerde bir tane olduğunu biliyordum).

Sunucu / denetleyici tarafında (bu, Node.js / Express'ten):

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

Orada ne yaptığımı gördün mü? Muhtemelen tanımlanmamış bir değişkenden sonra gelen && (yani request.session.survey_result, form verisine sahip olabilecek veya olmayabilecek nesne) JS'deki kısa devre gösterimidir. Yaptığı şey, yalnızca & & 'nin solundaki bölüm tanımsız DEĞİLSE & &' yi takip eden bölümü değerlendirmektir. Sol kısım IS olduğunda da hata vermez undefined. Sadece görmezden geliyor.

Şimdi, şablonumda (nesne req.session.survey_result_surveynesnesini görünümüme olarak aktardığımı unutmayın survey_result) ve sonra alanları şu şekilde oluşturdum:

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

Orada da sadece güvende tutmak için kısa devre kullandım.

Daha önce önerilen yollarla denediğimde, sadece:

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

Bazen, yine de IF ifadesi içindeki özellikleri değerlendirmeye çalışırdı ... Belki birisi neden diye bir açıklama sunabilir?

Ayrıca bunu düzeltmek istedim undefined önceki örneklerde yapıldığını gördüğüm gibi, bunun tek tırnaksız olması gerektiğini . trueBir String değerini 'undefined'bir veri türüyle karşılaştırdığınız için koşul asla olarak değerlendirilmez undefined.


0

Bu numarayı kullanabilirsin:

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

kapsam, kullanıcının üst nesnesidir


0

aynı nesneyi sık sık kullanmayı planlıyorsanız, aşağıdaki gibi bir işlev kullanabilirsiniz:

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

kullanımı:

<% if(userObj('name')){
    <h2><%= userObj('name') %></h2>
} %>

0

Başka bir çözüm buldum.

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

Umarım bu yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.