0
votes

I'm learning Marionette from a couple of days and some things are taking too much time get my head into it.

One thing I really would like to know is: Why Marionette ItemViews must have a template?

I made a simple example of a Backbone TableView. The concept is:

  • A view for the table
  • A view for the table row
  • A view for the table cell
  • A collection for the rows
  • The cells are made based on the number of properties of the model, meaning that if I add/remove a property a new cell is added/removed without the need to do any change at all.

Here is a fiddle http://fiddle.jshell.net/darksoulsong/4HK3D/8/ so you can have a much better view from what I'm refering to. Part of the code follows below:

var Model = Backbone.Model.extend({});
var Collection = Backbone.Collection.extend({
    model: Model
});

var TableCellView =  Backbone.View.extend({
    tagName: 'td',
    render: function (attr) {
        this.$el.append(attr);
        return this;
    }
});

var TableRowView = Backbone.View.extend({
    tagName: 'tr',
    addOne: function (attr) {
        var tableCell = new TableCellView();
        this.$el.append(tableCell.render(attr).$el);
    },
    render: function (model) {
        _.each(model, function (attr) {
            this.addOne(attr);
        }, this);
        return this;
    }
});

var TableView = Backbone.View.extend({
    initialize: function (options) {
        this.cols = options.cols;
    },
    tagName: 'table',
    className: 'table table-hover table-bordered',
    renderThead: function () {
        var thead = $('<thead>');
        var tr = $('<tr>');
        _.each(this.cols, function (value, index) {
            var th = $('<th>').html(value);
            tr.append(th);
        }, this);
        return thead.html(tr);
    },
    renderTbody: function (content) {
        var tbody = $('<tbody>');
        return tbody.html(content);
    },
    addOne: function (model) {
        var tableRow = new TableRowView();
        var tbody = this.renderTbody(tableRow.render(model).$el);
        this.$el.append(tbody);
    },    
    render: function () {
        this.$el.append(this.renderThead());
        this.collection.each(function (model) {
            this.addOne(model.toJSON());
        }, this);
        return this;
    }
});

var users = new Collection([
    {
        firstName: 'Jack',
        lastName: 'Johnson',
        age: '34'
    }, {
        firstName: 'Georgina',
        lastName: 'Jensen',
        age: '22'
    }, {
        firstName: 'Christyne',
        lastName: 'Swanson',
        age: '43'
    }]
);

var cols = ['First Name', 'Last Name', 'Age'];

var table = new TableView({'collection': users, 'cols': cols});

$('#users').html(table.render().$el); 

I know I can use a Marionette CompositeView for this, but there are some things I don't know how to handle:

  • A CompositeView needs a template. I don't have and don't need one, because everything is made dinamically.

  • The same goes for the ItemView: the table cells are dynamic as well. If I add a collection property this is automatically reflected to the view construction, without having to modify templates.

Any help would be great!

1

1 Answers

0
votes

Instead of CompositeView you can use CollectionView - it doesn't require a template. And for your ItemView you can use empty template:

Backbone.Marionette.ItemView.extend({
  template : _.template('')
});

But I would recommend to create and use a template.