rogergl
rogergl

Reputation: 3771

How to properly use Marionette layouts?

my current code looks like this:

define([
    'jquery',
    'underscore',
    'backbone',
    'marionette',
    'templates',
    'gridView',
    'detailView',
    'detailModel'
], function ($, _, Backbone, Marionette, JST, GridView, DetailView, DetailModel) {

    'use strict';

    return  Marionette.Layout.extend({

        el: '#main',

        template: JST['app/scripts/templates/main.ejs'],

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

        onRender: function () {
            var Layout = Marionette.Layout.extend({
                el: 'div',

                template: _.template(""),

                regions: {
                    grid: '#grid',
                    detail: '#detail'
                }
            });
            this.layout = new Layout();
            this.layout.render();
        },

        showGrid: function () {
            var detailModel = new DetailModel();

            var g = new GridView(detailModel);
            var d = new DetailView(detailModel);

            this.layout.grid.show(g);
            this.layout.detail.show(d);
        }

    });

});

What I do not understand is why I need an extra layout in my onRender method to make this work. The '#grid' and '#detail' divs are part of the main.ejs template, but the following does not work:

 return  Marionette.Layout.extend({

    el: '#main',

    template: JST['app/scripts/templates/main.ejs'],

    regions: {
        grid: '#grid',
        detail: '#detail'
    },

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

    onRender: function () {
        var detailModel = new DetailModel();

        var g = new GridView(detailModel);
        var d = new DetailView(detailModel);

        this.grid.show(g);
        this.detail.show(d);
    }

});

It seems that the layout only works if the elements specified in the region object already exist when the layout is created. But the documentation says that this is not the case.

I'm probably doing something wrong. But what ?

Regards Roger

Upvotes: 3

Views: 1831

Answers (2)

Avery S.
Avery S.

Reputation: 86

As an additional warning, calling .show() in the onRender method can negatively impact anything nested below that layout, especially if you are trying to use onShow later down the line to ensure that a view's DOM subtree is jQuery accessible.

.show() triggers a "show" event across any subviews of that layout and can mean that onShow() is called in those subviews (which listen for the "show" event) before those subviews have rendered and inserted their content.

Upvotes: 2

David Sulc
David Sulc

Reputation: 25994

In your second code example, try using onShow instead of onRender.

In addition, in Marionette you usually don't call render yourself, since the framework will call that method when you pass view/layouts to the show method.

You can see a different take on what you're trying to accomplish here :

Upvotes: 4

Related Questions