Zapomniałem o tym, że uruchomiłem ten sam problem i ustaliłem schemat korzystania z systemu zdarzeń Marionetki, aby widoki przekazały swój status przed uruchomieniem programu show(). Używam również requireJS, który dodaje dodatkową złożoność - ale ten wzór pomaga!
Będę mieć jeden widok z elementem interfejsu, który po kliknięciu wywoła zdarzenie, aby załadować nowy widok Może to być subview lub navview - nie ma znaczenia.
App.execute('loadmodule:start', { module: 'home', transition: 'left', someOption: 'foo' });
To zdarzenie jest złapany przez Wreqr „setHandlers” i uruchamia sekwencję widok ładowania (w moim przypadku robię sporo logiki do obsługi przejścia między stanami). Sekwencja "start" pojawia się w nowym widoku i przekazuje niezbędne opcje.
var self = this;
App.commands.setHandlers({'loadmodule:start': function(options) { self.start(options);
Następnie widok ładujący obsługuje kolekcje/modele i pobieranie podczas initalize. Widok nasłuchuje zmian modelu/kolekcji, a następnie uruchamia nowe "gotowe" zdarzenie za pomocą komendy execqr's.
this.listenTo(this.model, 'change', function(){
App.execute('loadmodule:ready', { view: this, options: this.options });
});
Mam inny obsługi, że połowy że gotowy zdarzeń (i opcje, w tym widoku opject odniesienia) i wyzwala 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;
Spróbuję napisać porządny sens całego systemu i opublikować go w przyszłym tygodniu.
Czy nie byłoby łatwiej opóźnić 'app.content.show()' do momentu pobrania? To by spowodowało opóźnienie renderowania widoku do czasu, aż model zostanie pobrany. –
Jeśli zamiast tego chcesz pokazać wiadomość ładującą, zajrzyj na https://github.com/marionettejs/backbone.marionette/wiki/Displaying-A-%22loading-...%22-Message-For- A-Collection-Or-Composite-View –