Создание процесса мастера в backbone.js

Я новичок в backbone.js, и у меня возникли проблемы с обдумыванием проблемы, с которой я разрабатываю процесс типа «мастер» (также известный как многоэтапная форма). Этот мастер должен иметь возможность обрабатывать различную логику ветвления экрана в зависимости от ответа пользователя на вопросы, сохранять ответы на каждый экран по мере продвижения пользователя и, в конце концов, иметь возможность сериализовать все ответы формы (каждый шаг) в один большой объект. (вероятно, JSON). Вопросы мастера будут меняться из года в год, и мне нужно иметь возможность одновременно поддерживать несколько похожих мастеров.

Я освоил основы создания экранов (используя backbone-forms), но теперь я подошёл к тому моменту, когда хочу сохранить пользовательский ввод, и не могу придумать, как это сделать лучше всего. Это. Большинство примеров, которые я видел, имеют один конкретный тип объекта (например, Todo), и вы просто создаете их коллекцию (например, TodoList), но у меня есть смешанный набор определений Backbone.Model из-за разных типов экранов, поэтому это не кажется таким простым. Любые указатели на то, как я должен создавать экземпляр своего мастера и содержащиеся в нем экраны, а также записывать ответы пользователей?

Если это поможет, я могу опубликовать jsfiddle с моим кодом просмотра, который пока только перемещает экраны вперед и назад (без записи ответа пользователя или ветвления экрана).

var Wizard = Backbone.Model.extend({

    initialize: function(options) {
        this.set({
            pathTaken: [0]
        });
    },

    currentScreenID: function() {
        return _(this.get('pathTaken')).last();
    },

    currentScreen: function() {
        return this.screens[this.currentScreenID()];
    },

    isFirstScreen: function(screen) {
        return (_(this.screens).first() == this.currentScreen());
    },

    // This function should be overridden by wizards that have
    // multiple possible "finish" screens (depending on path taken)
    isLastScreen: function(screen) {
        return (_(this.screens).last() == this.currentScreen());
    },

    // This function should be overridden by non-trivial wizards
    // for complex path handling logic
    nextScreen: function() {
        // return immediately if on final screen
        if (this.isLastScreen(this.currentScreen())) return;
        // otherwise return the next screen in the list
        this.get('pathTaken').push(this.currentScreenID() + 1);
        return this.currentScreen();
    },

    prevScreen: function() {
        // return immediately if on first screen
        if (this.isFirstScreen(this.currentScreen())) return;
        // otherwise return the previous screen in the list
        prevScreenID = _(_(this.get('pathTaken')).pop()).last();
        return this.screens[prevScreenID];
    }
});

var ChocolateWizard = Wizard.extend({
    nextScreen: function() {
        //TODO: Implement this (calls super for now)
        //      Should go from screen 0 to 1 OR 2, depending on user response
        return Wizard.prototype.nextScreen.call(this);
    },
    screens: [
        // 0
        Backbone.Model.extend({
            title : "Chocolate quiz",
            schema: {
                name: 'Text',
                likesChocolate:  {
                    title: 'Do you like chocolate?',
                    type: 'Radio',
                    options: ['Yes', 'No']
                }
            }
        }),
        // 1
        Backbone.Model.extend({
            title : "I'm glad you like chocolate!",
            schema: {
                chocolateTypePreference:  {
                    title: 'Which type do you prefer?',
                    type: 'Radio',
                    options: [ 'Milk chocolate', 'Dark chocolate' ]
                }
            }
        }),
        //2
        Backbone.Model.extend({
            title : "So you don't like chocolate.",
            schema: {
                otherSweet:  {
                    title: 'What type of sweet do you prefer then?',
                    type: 'Text'
                }
            }
        })
    ]
});

wizard = new ChocolateWizard();

// I'd like to do something like wizard.screens.fetch here to get
// any saved responses, but wizard.screens is an array of model
// *definitions*, and I need to be working with *instances* in
// order to fetch

Изменить: в соответствии с запросом я хотел бы, чтобы возвращаемое значение JSON для мастера, который был сохранен, выглядело примерно так (в качестве конечной цели):

wizardResponse = {
    userID: 1,
    wizardType: "Chocolate",
    screenResponses: [
      { likesChocolate: "No"},
      {},
      { otherSweet: "Vanilla ice cream" }
    ]
}
14
задан Abe Voelker 31 May 2012 в 17:59
поделиться