0
votes

I'm trying to preserve the full markup of a template, including the class on the root node when using a marionette region. I'm also trying to avoid creating an extra wrapping div. I've solved the problem, but in a way which I don't think is satisfactory.

I am creating and rendering a layout like this:

MyApp = new Backbone.Marionette.Application();
MyApp.addRegions({
    mainRegion: "#main"
});

AppLayout = Backbone.Marionette.Layout.extend({
    template: '
        <div class="row">
            <div class="col-md-8"></div>
            <div class="col-md-4"></div>
        </div>
    '
});
var layout = new AppLayout();

MyApp.mainRegion.show(layout);

layout.show(new MenuView());

And the result is that my template is rendered like this:

<div id="main">
    <div>
        <div class="col-md-8"></div>
        <div class="col-md-4"></div>
    </div>
</div>

Notice, the class="row" is missing from the root node of the template. It appears that marionette is removing the root div from my template, and then wrapping the contents in a new div.

I have managed to hack a solution to this like this

AppLayout = Backbone.Marionette.Layout.extend({
    template: '
        <div><!-- sacrificial div -->
            <div class="row">
                <div class="col-md-8"></div>
                <div class="col-md-4"></div>
            </div>
        </div>
    ',
    onRender: function () {
        // get rid of that pesky wrapping-div
        // assumes 1 child element.
        this.$el = this.$el.children();
        this.setElement(this.$el);
    }
});

I'm adding an extra root div (my sacrificial div) to my template which marionette removes, and then I'm telling marionette to use the first child as the layouts 'el' (as per Turning off div wrap for Backbone.Marionette.ItemView).

This seems crazy!

Can somebody suggest a better way?

EDIT: n.b. I'd like to keep all the template logic in the template, so don't want to have to use code in my view to specify the class on the root node - if I do this, I end up with a maintenance headache.

3

3 Answers

2
votes

Try with

AppLayout = Backbone.Marionette.Layout.extend({
    template: '
            <div class="col-md-8"></div>
            <div class="col-md-4"></div>
    ',
    className: "row"
});
0
votes

AppLayout is missing its region(s).

AppLayout = Backbone.Marionette.Layout.extend({
    template: '
        <div class="row">
            <div id="region1" class="col-md-8"></div>
            <div id="region2" class="col-md-4"></div>
        </div>
    ',
    regions: {
        region1: '#region1',
        region2: '#region2'
    }

});

Then at your instantiated layout:

layout.region1.show(new MenuView()); 
layout.region2.show(new MenuView()); 
0
votes

Instead of assigning the template to a string, compile the HTML into a template function with underscore. Something like this:

template: _.template(
  '<div class="row">' +
    '<div class="col-md-8"></div>' +
    '<div class="col-md-4"></div>' +
  '</div>'
)