我最近遇到了同样的问题,并决定使用 Marionette 的事件系统让视图在触发 show() 之前传达它们的状态。我也在使用 requireJS,它增加了一些额外的复杂性——但这种模式有帮助!
我将有一个带有 UI 元素的视图,当单击该元素时,会触发一个事件以加载新视图。这可能是子视图或导航视图 - 没关系。
App.execute('loadmodule:start', { module: 'home', transition: 'left', someOption: 'foo' });
该事件被 Wreqr 'setHandlers' 捕获并触发视图加载序列(在我的情况下,我正在执行一堆逻辑来处理状态转换)。“开始”序列初始化新视图并传入必要的选项。
var self = this;
App.commands.setHandlers({'loadmodule:start': function( options ) { self.start( options );
然后正在加载的视图处理集合/模型并在初始化时获取。视图监听模型/集合的变化,然后使用 wreqr 的 executre 命令触发一个新的“就绪”事件。
this.listenTo( this.model, 'change', function(){
App.execute('loadmodule:ready', { view: this, options: this.options });
});
我有一个不同的处理程序来捕获该就绪事件(和选项,包括视图对象引用)并触发 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;
我将尝试写下整个系统的体面要点,并在下周左右发布到这里。