Cannot get backbone view to render

64 Views Asked by At

I looping through a collection in an attempt to add a row to a table on every loop. Here is the code that loops the collection, and build the single view,

App.Views.OrganisationMembersTab = Backbone.View.extend({

el: '#members',

template: _.template( $('#tpl-members-tab-panel').html() ),

events: {

},

initialize: function() {
    this.$el.html( this.template() );
    this.render();
},

render: function() {
    this.addAll();
},

addAll: function() {
    this.collection.each( this.addOne, this);
},

addOne: function(model) {
    console.log(model);
    var tableRow = new App.Views.OrganisationsMemberRow({
        model: model
    });
    tableRow.render();
}

});

The single view that gets called to build the row looks like this,

App.Views.OrganisationsMemberRow = Backbone.View.extend({

    el: '.members-list tbody',

    template: _.template($('#tpl-organisation-member-row').html() ),

    events: {

    },

    initialize: function() {

    },

    render: function() {

        this.$el.prepend( this.template({
            member: this.model.toJSON()
        }));

        return this;
    }

});

The model that is being used once it has been parsed to JSON using toJSON() looks like this,

email: "[email protected]"  
first_name: "John"  
last_name: "Doe"  

The template for the row looks like this,

<script type="text/template" id="tpl-members-tab-panel">

    <table class="table table-striped members-list">

        <thead> 

            <tr>
                <th>A</th>
                <th>B</th>
                <th>C</th>
                <th>D</th>
            </tr>

        </thead>

        <tbody>
            <tr>
                <td colspan="4"><button class="btn btn-success btn-sm pull-right">Add &plus;</button></td>
            </tr>
        </tbody>

    </table>

</script>

The above builds the main table components, and the next template is actually for a data row.

<script type="text/template" id="tpl-organisation-member-row">
    <tr>
        <td>#</td>  
        <td><%= first_name %> <%= last_name %></td>
        <td>Admin <input type="checkbox" /></td>
        <td>Remove</td>
    </tr>

</script>

All I get output the the main table and then in the main tbody I get either nothing prepended or an empty <tr> why is this?

2

There are 2 best solutions below

4
On

Your current implementation is a little confused. Your row view has no tagName so by default you'll be appending divs to your tbody.

The first thing I'd do is take the <tr> tag out of your tpl-organisation-member-row template and then alter your row view like so:

App.Views.OrganisationsMemberRow = Backbone.View.extend({

    tagName: 'tr',

    template: _.template($('#tpl-organisation-member-row').html() ),

    render: function() {
       this.$el.html(this.template(this.model.toJSON()));
       return this;
    }
});

Member row template:

<script type="text/template" id="tpl-organisation-member-row">
        <td>#</td>  
        <td><%= first_name %> <%= last_name %></td>
        <td>Admin <input type="checkbox" /></td>
        <td>Remove</td>
</script>

Then I'd prefer to control appending the rows from your App.Views.OrganisationMembersTab view. So in your addOne method do the following:

addOne: function(){
    var tableRow = new App.Views.OrganisationsMemberRow({
        model: model
    });
    this.$('tbody').append(tableRow.render().el);
}
0
On

The problem is with your template which doesn't use member property, just use whole model instead.

You need replace

    this.$el.prepend( this.template({
        member: this.model.toJSON()
    }));

with

    this.$el.prepend( this.template(
        this.model.toJSON()
    ));

working example