这不是骨干/木偶问题,更多是纯粹的JavaScript问题。如果你不关心可用性,只需使用window.prompt并为自己节省很多工作。
如果您无法使用alert
s,则情况会变得更加复杂。用户输入通常使用某种形式完成。不幸的是,这些都是异步操作,这意味着你不能停止JavaScript执行,而是等待用户拿出眼镜寻找他们的SSN。 jQuery's Deferred library是一个很好的工具来处理这些情况,但你需要稍微修改一下你的代码。
在我们的项目中,我们已经创建了一个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... */ },
};
接下来我们有推动通过每个状态的生命周期生命周期沃克对象;它看起来是这样的(从内存中,你要测试这个...)
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
上做类似的事情。