rkw
rkw

Reputation: 7297

View Rendering: Is there a better way to control the class name for the view element?

var myView = Backbone.View.extend({
    tagName: 'div',
    className: function() {
        return this.model.isNew() ? 'new' : 'old';
    }

That's the functionality I would like, but it doesn't work. I'm not sure when the class name is determined, but the callee is just the element itself; in this case, it would be <div></div>. Is there a way to give className access to the model?

I can, and currently, put another div in my template, in order to control the class, but that div is definitely not needed if I am able to control the class name from the View itself.

Upvotes: 1

Views: 649

Answers (3)

Mustafa D&#252;man
Mustafa D&#252;man

Reputation: 152

Alternatively, you could avoid className property and use attributes function...

var myView = Backbone.View.extend({
    tagName: 'div',
    attributes: function() {
        return { "class": this.model.isNew() ? 'new' : 'old'
            };
    }
});

Upvotes: 1

Paul
Paul

Reputation: 18597

You need to set the context of the className function by using _.bindAll in the initialize method

var myView = Backbone.View.extend({
  initialize: function() {
    _.bindAll(this, 'className');
  },
  tagName: 'div',
  className: function() {
    return this.model.isNew() ? 'new' : 'old';
  }
});

Upvotes: 2

Rob Hruska
Rob Hruska

Reputation: 120346

If it were me, I'd probably set that type of class within render() use a helper function:

var myView = Backbone.View.extend({
    render: function() {
        this.applyClass();
        return this;
    },

    applyClass: function() {
        var isNew = this.model.isNew();
        $(this.el)
            .toggleClass('new', isNew)
            .toggleClass('old', !isNew);
    }
});

You could then reuse applyClass in an event handler later if you need to:

    initialize: function(options) {
        this.model.bind('change', this.applyClass, this);
    }

Upvotes: 6

Related Questions