Gleeb
Gleeb

Reputation: 11289

why is the tag in backbone.js view rendering all of the model attributes into itself

I am working with backbone.js and i am trying to understand if i am doing something wrong or is this how backbone should behave.

i am building a table, for that i have 2 templates the first one is all the container and <thead> information which are irrelevant for the question.

then i am rendering the collection of items into rows. with this view:

   MYAPP.Menu.ItemView = Backbone.View.extend({
    tagName: 'tr',      
    template: template('menu-item'),
    initialize : function(modelItem) {
    this.model = modelItem;
    this.model.on('all', this.render, this);
    },
    render : function() {
        var html = this.template(this.model.toJSON());
        this.$el.html(html);
        return this;
    }
});

this is the template for menu-item:

  <script type="text/x-mustache-template" id="menu-item-template">
            <td>{{title}}</td>
            <td>{{description}}</td>
            <td>{{price}}</td>
            <td>{{status}}</td>
            <td></td>
    </script>

the output that i am getting inside the <tbody> tag is this:

     <tr id="1" title="title1" price="price1">
            <td>title1</td>
            <td></td>
            <td>price1</td>
            <td></td>
            <td></td>
    </tr>

and so on. SO HERE COMES THE QUESTION

Why is all the data stored inside the <tr> tag as attributes? i don't want that. why is it there?

Thanks.

Upvotes: 3

Views: 409

Answers (1)

jevakallio
jevakallio

Reputation: 35950

You're most likely initializing your view like this:

new MYAPP.Menu.ItemView(someModel);

This is incorrect, the correct way is to pass a model in an options object using the key model:

new MYAPP.Menu.ItemView({model:someModel});

The fact that the model attributes are being set as the element's attributes is just a bit of a unlucky coincidence in naming. Internally Backbone.Model stores its values in a property called attributes. Backbone.View on the other hand accepts an option called attributes in the options argument, and copies that over to View.attributes, which in turn sets those as attributes on the root element.

There are some special properties which are copied to the view automatically: id, cssClass, el, model and collection, just to name a few. Because a model is just an object, calling new View(model) is equivalent to new View({id:id, attributes:attributes, ...}), and that causes the curious effect you're seeing.

So looking at your constructor code, it should look like this:

initialize : function(options) {
   this.model = options.model;
   this.model.on('all', this.render, this);
}

But because Backbone takes care of setting some of the View's options for your, including model, you don't strictly speaking even need to set this.model:

initialize : function(options) {
   this.model.on('all', this.render, this);
}

Upvotes: 10

Related Questions