这不是一个 Backbone/Marionette 问题,而是一个纯粹的 JavaScript 问题。如果您不关心可用性,只需使用window.prompt并为自己节省大量工作。
如果您不能使用alert
s,那么事情会变得更加复杂。用户输入通常使用某种形式完成。不幸的是,这些是异步操作,这意味着您不能在等待用户摘下眼镜并寻找他们的 SSN 时停止 JavaScript 执行。jQuery 的 Deferred 库是处理此类情况的好工具,但您需要稍微修改代码。
在我们的项目中,我们创建了一个 a 的概念,Lifecycle
大致如下:
Module.lifecycle = {
step1: function() {
var dfd = new $.Deferred().resolve();
// get user input from a custom dialog control
var dialog = new MyDailogControl("What do you want to do?");
dialog.onSuccess = dfd.resolve;
dialog.onFail = dfd.reject;
dialog.show();
return dfd.promise();
},
step2: function() { /* load some data from the server */ },
step3: function() { /* get even more user input... */ },
};
接下来我们有一个 Lifecycle Walker 对象,它通过每个状态推动生命周期;它看起来像这样(从记忆中;你会想要测试这个......)
var Walker = function(lifecycle) {
this.lifecycle = lifecycle;
this._states = _.keys(this.lifecycle);
}
_.extend(Walker.prototype, Backbone.Events, {
start: function() {
this._index = 0;
this.moveNext();
},
moveNext: function() {
var step = this.states[this._index];
this.trigger('before:' + step);
$.when(this.lifecycle[step]())
.then(function() {
this.trigger('after:' + step);
this._index++;
if (this._active < this._states.length) {
this.moveNext();
}
});
}
});
将这两个想法结合在一起,您将执行以下操作:
var walker = new Walker(MyModule.lifecycle);
walker.on('before:step1', function() { /* do something amazing */ });
walker.on('before:step2', function() { /* do something fantastic */ });
walker.on('after:step3', function() { /* do whatever */ });
walker.start();
所以,我们基本上实现了一个混蛋命令模式,使用延迟来解决这样的问题。我们挂钩module.start
,但没有理由你不能做类似的事情app.start
。