1
votes

I am exploring a setup with HandelbarsJS and Backbone.

This is part of my template:

<a href="#genre/{{ name }}" class="genre-item" data-genre="{{ name }}">
  <i class="icon-chevron-{{#if is_selected }}down{{else}}right{{/if}}"></i>
  {{ display_name }} ({{ total }})
</a>

Meaning: I want to render a different icon, depending on whether a model is selected or not. However, I never get the 'icon-chevron-down', but always the 'icon-chevron-right' path. Any ideas what I am missing?

EDIT

The selection of a Genre is working on model level like this:

MA.Models.Genre = Backbone.Model.extend({
    defaults: {
        selected: false
    },

    is_selected: function() {
        return (this.get('selected') == true);
    },

    toggle: function() {
        if (this.is_selected()) {
            this.set('selected', false);
        }
        else
        {
            this.set('selected', true);
        }
    }
});

MA.Collections.Categories = Backbone.Collection.extend({
    model: MA.Models.Genre  
});

This could probably be simplified, but I am not getting the selection of the Genre from the remote service, but it is used just as a temporary state change.

1

1 Answers

2
votes

Without seeing what is happening in your view it's hard to tell. But you probably have a render function that look's like:

HandlebarsTemplate['templatename'](this.model.toJSON());

toJSON by default only includes model attributes. Also handlebars won't evalute functions on the fly like that.

The easiest solution is to fix the template to look like:

<a href="#genre/{{ name }}" class="genre-item" data-genre="{{ name }}">
    <i class="icon-chevron-{{#if selected }}down{{else}}right{{/if}}"></i>
    {{ display_name }} ({{ total }})
</a>

I've changed is_selected to selected to use the attribute instead of the function.

The other option is to modify the toJSON function of the model to include the evaluated function:

MA.Models.Genre = Backbone.Model.extend({
    defaults: {
        selected: false
    },

    is_selected: function() {
        return (this.get('selected') == true);
    },

    toJSON: function(options) {
        var attrs = _.clone(this.attributes);
        attrs.is_selected = this.is_selected();
        return attrs;
    }
});