ChatGPT解决这个技术问题 Extra ChatGPT

How to use if statements in underscore.js templates?

I'm using the underscore.js templating function and have done a template like this:

<script type="text/template" id="gridItem">
    <div class="griditem <%= gridType %> <%= gridSize %>">
        <img src="<%= image %>" />
        <div class="content">
            <span class="subheading"><%= categoryName %></span>
            <% if (date) { %><span class="date"><%= date %></span><% }  %>
            <h2><%= title %></h2>
        </div>
    </div>
</script>

As you can see I have an if statement in there because all of my models won't have the date parameter. However this way of doing it gives me an error date is not defined. So, how can I do if statements within a template?


S
Stephen Fuhry

This should do the trick:

<% if (typeof(date) !== "undefined") { %>
    <span class="date"><%= date %></span>
<% } %>

Remember that in underscore.js templates if and for are just standard javascript syntax wrapped in <% %> tags.


Works great, and just discovered that JS switch/case statements work nicely in template markup, too.
Awesome answer. Can you please also tell how can I use alternating classes when I am using templates? Like first
  • should get class a and next b?
  • @BlackDivine I know it's kind of late, but for alternating styles you should use :nth-child(even) and :nth-child(odd) CSS selectors, not change your template.
    its looking same as java scriptlets used for rendering variables in jsp
    I ended up with this line at the end {{ } }}, because I had to change the <% %> wrapper and it still worked.
    T
    TonyTakeshi

    If you prefer shorter if else statement, you can use this shorthand:

    <%= typeof(id)!== 'undefined' ?  id : '' %>
    

    It means display the id if is valid and blank if it wasn't.


    Conditional operator, which gets the nickname "ternary" since it's the only common ternary operator (three-operands).
    Note that an occasional shortcoming of the technique proposed in this answer is that you're stuck doing string interpolation all over again, which templates are supposed to solve for you. As of right now, _.template inserts a ; at the start of each compiled code tag. Thus, it can handle tags breaking between statements, but not inside of expressions. Compare;if(a){b;}else{c;} to ;a?b;:c;.
    S
    SunnyRed

    Depending on the situation and or your style, you might also wanna use print inside your <% %> tags, as it allows for direct output. Like:

    <% if (typeof(id) != "undefined") {
         print(id);
    }
    else {
        print('new Model');
    } %>
    

    And for the original snippet with some concatenation:

    <% if (typeof(date) != "undefined") {
        print('<span class="date">' + date + '</span>');
    } %>
    

    Y
    Yasser Shaikh

    Here is a simple if/else check in underscore.js, if you need to include a null check.

    <div class="editor-label">
        <label>First Name : </label>
    </div>
    <div class="editor-field">
        <% if(FirstName == null) { %>
            <input type="text" id="txtFirstName" value="" />
        <% } else { %>
            <input type="text" id="txtFirstName" value="<%=FirstName%>" />
        <% } %>
    </div>
    

    null is not the same as undefined, it would still produce an error
    In this case it wouldn't matter, since he checks the value using ==, which will convert the value. Because of the type-conversion the following statement is true: null == undefined - Not endorsing that, just saying.
    I think it's better to use _.isEmpty()
    S
    Snowmonkey

    Responding to blackdivine above (about how to stripe one's results), you may have already found your answer (if so, shame on you for not sharing!), but the easiest way of doing so is by using the modulus operator. say, for example, you're working in a for loop:

    <% for(i=0, l=myLongArray.length; i<l; ++i) { %>
    ...
    <% } %>
    

    Within that loop, simply check the value of your index (i, in my case):

    <% if(i%2) { %>class="odd"<% } else { %>class="even" <% }%>
    

    Doing this will check the remainder of my index divided by two (toggling between 1 and 0 for each index row).


    D
    Damien

    You can try _.isUndefined

    <% if (!_.isUndefined(date)) { %><span class="date"><%= date %></span><% } %>
    

    Beware the difference between "date is undefined" and "date is not defined". They should have called that error "No variable or global property exists with the name 'date'." The code you've proposed will still throw an exception if date doesn't exist at all. You really do need the typeof in this case, although it would be even better to use a named variable when we're duck-typing template data.
    A
    Anna T

    From here:

    "You can also refer to the properties of the data object via that object, instead of accessing them as variables." Meaning that for OP's case this will work (with a significantly smaller change than other possible solutions):

    <% if (obj.date) { %><span class="date"><%= date %></span><% }  %>
    

    M
    Markus

    To check for null values you could use _.isNull from official documentation

    isNull_.isNull(object)
    

    Returns true if the value of object is null.

    _.isNull(null);
    => true
    _.isNull(undefined);
    => false