I've recenlty run into the same issue and settled on a pattern of using Marionette's event system to let the views communicate their status before firing show(). I'm also using requireJS which adds some additional complexity - but this pattern helps!
I'll have one view with a UI element that when clicked, fires an event to load a new view. This could be a subview or a navview - doesn't matter.
App.execute('loadmodule:start', { module: 'home', transition: 'left', someOption: 'foo' });
That event is caught by the Wreqr 'setHandlers' and triggers a view loading sequence (in my case I'm doing a bunch of logic to handle state transitions). The 'start' sequence inits the new view and passes in necessary options.
var self = this;
App.commands.setHandlers({'loadmodule:start': function( options ) { self.start( options );
Then the view getting loading handles the collections / models and fetching on initalize. The view listens for model / collection changes and then fires a new "ready" event using wreqr's executre command.
this.listenTo( this.model, 'change', function(){
App.execute('loadmodule:ready', { view: this, options: this.options });
});
I have a different handler that catches that ready event (and options, including the view opject reference) and triggers the show().
ready: function( options ) {
// catch a 'loadmodule:ready' event before proceeding with the render / transition - add loader here as well
var self = this;
var module = options.options.module;
var view = options.view;
var transition = options.options.transition;
var type = options.options.type;
if (type === 'replace') {
self.pushView(view, module, transition, true);
} else if (type === 'add') {
self.pushView(view, module, transition);
} else if (type === 'reveal') {
self.pushView(view, module, transition, true);
}
},
pushView: function(view, module, transition, clearStack) {
var currentView = _.last(this.subViews);
var nextView = App.main.currentView[module];
var self = this;
var windowheight = $(window).height()+'px';
var windowwidth = $(window).width()+'px';
var speed = 400;
switch(transition) {
case 'left':
nextView.show( view );
nextView.$el.css({width:windowwidth,left:windowwidth});
currentView.$el.css({position:'absolute',width:windowwidth,left:'0px'});
nextView.$el.animate({translate: '-'+windowwidth+',0px'}, speed, RF.Easing.quickO);
currentView.$el.animate({translate: '-'+windowwidth+',0px'}, speed, RF.Easing.quickO, function(){
if (clearStack) {
_.each(_.initial(self.subViews), function( view ){
view.close();
});
self.subViews.length = 0;
self.subViews.push(nextView);
}
});
break;
I'll try to write up a decent gist of the whole system and post here in the next week or so.
app.content.show()
till after the fetch? That would for all purposes delay rendering the view till the model is fetched. – Amith George