Ожидание ввода пользователя, прежде чем перейти к следующему этапу приложения Marionette.
Моему приложению нужна функция, которую нужно вызывать при initialize: after stage. После того, как пользователь предоставил этот вход в функцию, я хочу, чтобы приложение перешло в начальную стадию. Но в настоящее время, это просто пройти все 3 этапа, не дожидаясь ввода. Кто-нибудь может подсказать, как мне добиться желаемой функциональности?
var app= new Marionette.Application();
app.on('initialize:before', function(options){
//do Something
});
app.on('initialize:after', function(options){
//do Something
//wait for User to give input before continuing to start stage.
});
app.on('start', function(options){
//start only when User provide input.
//do Something with input.
});
var options = {};
app.start(options);
1 ответ
Это не столько вопрос о Backbone/Marionette, сколько проблема с чистым JavaScript. Если вас не волнует удобство использования, просто используйте window.prompt и сэкономьте много работы.
Если вы не можете использовать alert
с, то все становится сложнее. Пользовательский ввод обычно выполняется с использованием какой-либо формы. К сожалению, это асинхронные операции, а это означает, что вы не можете просто остановить выполнение JavaScript, пока вы ждете, когда пользователь достанет свои очки и ищет свой SSN. Отложенная библиотека jQuery - хороший инструмент для обработки подобных ситуаций, но вам нужно немного переделать свой код.
В нашем проекте мы создали концепцию 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
вместо.