user1368258
user1368258

Reputation: 71

Using functions in a underscore template

I am trying to use a function in an Underscore template as shown here but I am getting an error:

Uncaught ReferenceError: getProperty is not defined

Below is the code I am using

var CustomerDetailView = Backbone.View.extend({
    tagName : "div",
    template: "#customer-detail-view-template",

    initialize: function() {
        _.bindAll(this, 'render');
        this.model.bind('change', this.render);
        this.initializeTemplate();
    },

    initializeTemplate: function() {
        this.template = _.template($(this.template).html());
    },

    render: function() {
        var data = this.model.toJSON();
        _.extend(data, viewHelper);
        console.log(data);
        var html = _.template($(this.template), data);
        $(this.el).html(html);
        return this;
    }
})

And the template:

 <script type="text/template" id="customer-detail-view-template">
    <div style="height: 70px;">
        <span class="displayText">
            <p class="searchResultsAuxInfo">Full Name : <%= getProperty("full_name", null) %> </p>
            <p class="searchResultsAuxInfo">Country Code : <%= getProperty("country_code", null) %></p>
            <p class="searchResultsAuxInfo">street : <%= getProperty("street", null) %></p>
            <p class="searchResultsAuxInfo">maiden_name : <%= getProperty("maiden_name", null) %></p>
        </span>
        <span class="displayTextRight">
            <p class="searchResultsAuxInfo">marital_status_code : <%= getProperty("marital_status_code", null) %></p>
            <p class="searchResultsAuxInfo">tax_id_number : <%= getProperty("tax_id_number", null) %></p>
            <p class="searchResultsAuxInfo">primary_phone : <%= getProperty("primary_phone", null) %></p>
            <p class="searchResultsAuxInfo">customer_number : <%= getProperty("customer_number", null) %></p>
        </span>
    </div>
</script>

The view helper object looks like this:

var viewHelper = {
    getProperty:function(propertyName, object) {
        if(typeof(object) === "undefined"){
            object = this["attributes"];
        }
        for (i in object) {
            if (_.isObject(object[i])) {
                var currentObj = object[i];
                if(_.has(currentObj, propertyName)){
                    return currentObj[propertyName];
                }
                this.getProperty(propertyName, currentObj);
            }
        }
    }
}

Upvotes: 6

Views: 12124

Answers (2)

delai
delai

Reputation: 491

according to the blog article you refer to,

just delete this line will make it work: "this.initializeTemplate();"

Upvotes: 0

mu is too short
mu is too short

Reputation: 434665

Your problem is that once you're inside render, this.template:

var html = _.template($(this.template), data);

is already a compiled template function:

initializeTemplate: function() {
    this.template = _.template($(this.template).html());
}

The _.template call:

Compiles JavaScript templates into functions that can be evaluated for rendering.

So you're saying this:

_.template($(some_compiled_template_function).html(), data);
//           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

That is executing the $(function() { ... }) form of $() and that:

Binds a function to be executed when the DOM has finished loading.

That little bit of confusion makes everything go haywire and chaos abounds. Fix how you use the template and things will start making more sense:

render: function() {
    //...
    var html = this.template(data);
    //...
}

Your this.template will be a function inside render so call it as a function.

Demo (with some simplifications for clarity): http://jsfiddle.net/ambiguous/SgEzH/

Upvotes: 13

Related Questions