Kamran224
Kamran224

Reputation: 1614

Backbone.js don't include model properties in view

I have a model in Backbone.js like the following model:

Attribute = Backbone.Model.extend({
    defaults: {
        label: '',
        values: {},
    },
});

With this view:

AttributeView = Backbone.View.extend({
    tagName: 'button',
    className: 'btn',
    initialize: function(attribute) {
        this.attribute = attribute;
        this.render();
    },
    render: function() {
        var template = _.template($("#attribute-template").html(), {attribute: this.attribute});    
        this.$el.html(template);
    },
});

HTML template:

<!----- attribute template ----->
<script type="text/template" id="attribute-template">
    <span class="attr">
        <%= attribute.get('label') %>
    </span>
    <span class="badge pull-right"></span>
</script>

And it produces this:

<button label="..." values="[object Object],[object Object],..." class="btn">...</button>

My question is why does backbonejs add the label and values attributes to the html template and how can I prevent this?

Upvotes: 0

Views: 449

Answers (2)

Kamran224
Kamran224

Reputation: 1614

Turns out I was initializing the view incorrectly. I was passing in the model directly

var itemView = new ItemView(item)

instead I need to declare it as the model

var itemView = new ItemView({model: item})

Also didn't realize that attribute is a View property so I had to rename my model and views.

Upvotes: 1

T Nguyen
T Nguyen

Reputation: 3415

You have poorly chosen the name attributes to hold your model (why you're storing your model in a custom property is also beyond me), as Backbone.View.attributes is a property which is meant to specify HTML attributes to add to the view's el (which is your <button> tag - http://backbonejs.org/#View-attributes.

Typically, you would associate a model with a view by specifying a new instance of it in the model property, like below Then you can reference the model as this.model and if you need just the data, this.model.toJSON():

AttributeView = Backbone.View.extend({
    model: new Attribute(),
    tagName: 'button',
    className: 'btn',
    initialize: function() {
        this.render();
    },
    render: function() {
        var template = _.template($("#attribute-template").html(), this.model.toJSON());    
        this.$el.html(template);
    },
});

FYI, here is an example of the proper usage of the attributes property:

AttributeView = Backbone.View.extend({
    model: new Attribute(),
    tagName: 'button',
    className: 'btn',
    attributes: {
        'data-foobar': "I'm a custom data attribute"
    }
    initialize: function() {
        this.render();
    },
    render: function() {
        var template = _.template($("#attribute-template").html(), this.model.toJSON());    
        this.$el.html(template);
    },
});

This would then generate:

<button data-foobar="I'm a custom data attribute" class="btn">...</button>

Upvotes: 1

Related Questions