Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
            }
        }
    }
}
like image 879
user1368258 Avatar asked May 01 '12 17:05

user1368258


1 Answers

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/

like image 126
mu is too short Avatar answered Oct 12 '22 23:10

mu is too short