3

私は2つのレイアウトを持っています。最初のレイアウトは、サブ レイアウトのレンダリングを担当します (私のインターフェイスはかなり複雑なので、すぐにビュー付きの多くのサブ レイアウトになります)。

最初のレイアウトは次のとおりです。

App.module('Layouts', function(Layouts, App, Backbone, Marionette, $, _) {

    Layouts.Editor = Backbone.Marionette.Layout.extend({

        tagName: 'div',
        className: 'content container-fluid',

        regions: {
            stageContainer: '#stage-container',
        },

        initialize: function() {

            this.template = Backbone.Marionette.TemplateCache.get('editor');

        },

        render: function() {

            var _this = this;

            this.model = new App.Models.App();
            this.model.url = GLOBAL.api.url + '/clients/' + GLOBAL.cid + '/sweepstakes/' + GLOBAL.aid;
            this.model.fetch({ success: function() {

                // show template
                $(_this.el).html(_this.template());

                // show region content
                _this.showStageContainer();

            } });

        },

        showStageContainer: function() {

            var content = new App.Layouts.EditorStageContainer({
                model: this.model
            });
            this.stageContainer.show(content);

            return content;

        }

    });

});

これはうまくレンダリングされます。ただし、showStageContainer関数でサブ レイアウトをレンダリングしようとすると、render が呼び出されますが、コンテンツは実際にはレンダリングされません。モデルをレイアウト ビューと子ビューに渡す必要があるため、モデルを取得した後に showStageContainer を呼び出していることに注意してください。ステージ コンテナのレイアウトは次のようになります。

App.module('Layouts', function(Layouts, App, Backbone, Marionette, $, _) {

    Layouts.EditorStageContainer = Backbone.Marionette.Layout.extend({

        el: '#stage-container',
        tagName: 'div',

        regions: {
            nav: '#nav',
            progress: '#progress',
            stage: '#stage'
        },

        initialize: function() {

            this.template = Backbone.Marionette.TemplateCache.get('editor_stage_container');

        },

        render: function() {

            console.log('render');

            $(this.el).html(this.template());

        },

        onShow: function() {

            // TODO: figure out why the template has to be rendered on show rather
            // than in the render. (render is never being called as onRender is not called)
            $(this.el).html(this.template());

            // show region content
            this.showNav();

        },

        showNav: function() {

            var content = new App.Views.EditorStageNav();
            this.nav.show(content);

        }

    });

});

ご覧のとおり、onShow関数内でテンプレートを手動でレンダリングする必要があります。通常、これは関数内で自動的に行われrenderます。

最も興味深いのは$(this.el).html(this.template());、レンダリング関数で setTimeout をラップすると、すべてがうまくいくということです...これにより、何かが順番に実行されていないと思います。例:

var _this = this;
render: function() {
    setTimeout(function() {
        $(_this.el).html(_this.template());
    }, 1);
}

何かご意見は?ここで途方に暮れており、本当に助けが必要です。ありがとう!

4

2 に答える 2

2

I believe you are running into an issue with timing. The region stageContainer does not exist until after the DOM is rendered. Once the html is rendered, Marionette will point stageContainer to the element #stage-container. As you have found, you can easily access the region in the onRender method because onRender is kicked off after the DOM exists.

There are many work arounds and I find many of them so so. Personally I break this part of the application into smaller pieces by only rendering stageContainer after the parent container has been rendered.

**Edit

I just came across a link for a Marionette.js plugin called BossView. It looks interesting but most of all, it will give you example of both doing what you are asking in Marionette and then how to do it in BossView.

于 2013-09-23T23:28:10.853 に答える