Backbone 多步模态

Backbone Multi Step Modal

我正在创建一个 Twitter Bootstrap 多步骤模式。

这就是我试图让工作流程正常工作的方式:

  1. 用户点击按钮打开模态...模态打开
  2. 用户输入访问码,点击下一步
  3. 服务器检查访问代码是否存在。如果存在,用户将继续下一步,否则用户会收到错误消息。
  4. 用户输入账单信息。用户将支付的价格基于他们最初输入的访问代码。
  5. 模态显示交易确认信息和访问码

这是我的模态标记:

  section#paymentModal.modal.fade(tabindex='-1', role='dialog' aria-labelledby='paymentModalLabel' aria-hidden='true')
    div.modal-dialog
      div#paymentModalContent.modal-content
        div.modal-header
          button.close(data-dismiss='modal', aria-label='Close')
            span(aria-hidden="true")×
          h4#paymentModalLabel.modal-title Please enter your access code
        div#paymentModalBody.modal-body
        div.modal-footer
          button.btn-previous.btn.btn-warning.hide(type='button', data-orientation='previous') Previous
          button.btn-next.btn.btn-primary(type='button', data-orientation='next') Next Step

这是我的 backbone 模板:

  script(type="text/template", id="tmpl-accessCode")
    div.modal-header
      button.close(data-dismiss='modal', aria-label='Close')
        span(aria-hidden="true")×
      h4#paymentModalLabel.modal-title Please enter your access code
    div#paymentModalBody.modal-body
      input(type='text', placeholder='Enter Access Code')
    div.modal-footer
      button.btn-next.btn.btn-primary(type='button', data-orientation='next') Next Step

  script(type="text/template", id="tmpl-payment")
    div.modal-header
      button.close(data-dismiss='modal', aria-label='Close')
        span(aria-hidden="true")×
      h4#paymentModalLabel.modal-title Please enter your billing information
    div#paymentModalBody.modal-body
      // billing information goes here
    div.modal-footer
      button.btn-previous.btn.btn-warning.hide(type='button', data-orientation='previous') Previous
      button.btn-next.btn.btn-primary(type='button', data-orientation='next') Next Step

这是我的 JS:

(function() {
  'use strict';

  app = app || {};

  app.AccessCode = Backbone.Model.extend({
    url: '/accessCode/'
  });

  app.Payment = Backbone.Model.extend({
    url: '/payment/'
  });

  app.AccessCodeView = Backbone.View.extend({
    el: '#paymentModalContent',
    template: _.template( $('#tmpl-accessCode').html() ),
    events: {
      'click .btn-next': 'verifyAccessCode'
    },
    initialize: function() {
      this.model = new app.AccessCode();
      this.listenTo(this.model, 'sync', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));
    },
    verifyAccessCode: function() {
      var accessCode = this.model.set({'name': 'thomas'});
      accessCode.fetch({
        success: function() {
          // chance view to billing view
        },
        error: function() {
          console.log('Access code doesn\'t exist');
        }
      });
    }
  });

  app.BillingView = Backbone.View.extend({
    el: '#paymentModalContent',
    template: _.template( $('#tmpl-payment').html() ),
    initialize: function() {
      this.model = new app.Payment();
      this.listenTo(this.model, 'sync', this.render);
      this.render();
    },
    render: function() {
      this.$el.html(this.template( this.model.attributes ));
    }  
  });

  $(document).ready(function() {
    app.accessCodeView = new app.AccessCodeView();
  });
}());

我的问题是如何从 AccessCodeView 的成功函数回调中调用 BillingView?在另一个视图中调用一个视图不违反backbone原则吗?

另外,有没有比我目前采用的方法更好的方法?

感谢所有帮助和建议:)

更好的方法是分离数据加载和视图创建。这可以通过使用 Backbone.Events.

有效地完成
  1. 创建一个自定义 JS 对象,比如 AppController 并让它扩展 Backbone.Events。

    var AppController = _.extend({},Backbone.Events);

  2. 定义一个自定义事件和一个将显示加载数据和显示视图的事件处理程序。

    AppController.on("app:view_billing",function(payload){
       payload.accessCode.fetch().done(function() {
           // Create an instance of the billing view.
          // Update the url if required using the navigate method with trigger:false
       });
    });
    
  3. 从你的方法现在你可以做到这一点:

    verifyAccessCode: function(e) {
      var accessCode = this.model.set({'name': 'thomas'});
      var payLoad = {accessCode:this.accessCode};
      AppController.trigger("app:view_billing",payLoad);
    }