Ожидание ввода пользователя, прежде чем перейти к следующему этапу приложения 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 вместо.

Другие вопросы по тегам