手风琴向导在ember中有多个步骤

时间:2014-03-03 13:46:00

标签: ember.js architecture ember-data handlebars.js

我正在使用ember构建一个“精灵手风琴”

基本上我想要的是:

  • 一个总是显示的手风琴
  • 手风琴包含所有步骤
  • 一步有效,但也可能更改前一步骤的标题
  • 每个步骤都有自己的模型(例如,从第一步中选择国家,从第二步中选择产品)
  • 应该可以在步骤之间跳回来强制
  • 在所有选择中建立了一个中央模型,在最后一步之后将其发送到服务器
  • 步骤数是动态的,有时会跳过某些步骤

我想到的架构在应用程序模板中有3个出口:

  • {{previousSteps}}
  • {{出口}}
  • {{nextSteps}}

并始终在每个路线中渲染3个模板。每个步骤都有自己的路由和控制器,每个步骤的创建操作将共享模型保存到应用程序控制器并转换到下一步。

但我想这个解决方案到目前为止还不是最好的。有人有更好的架构吗? 特别是如何构建路由,控制器和模板

谢谢

Wizard Mockup更新

我现在正以下面的方式做这件事。我感谢对我的解决方案的任何评论。

App.Router.map(function() {
   this.resource('steps', { path: '/' });
});

App.StepsRoute = Ember.Route.extend({
  model: function() {
    return [
      { controllerName: 'countries', templateName: 'countries', items:    this.store.find('country') },
      { controllerName:  'products', templateName: 'products', items: this.store.find('product') }
    ]
  }
});

App.StepsController = Ember.ArrayController.extend({
  currentStep: "countries",

  transitionToStep: function(step) {
    this.set('currentStep', step);
  },

  lookupItemController: function(modelObject) {
    return modelObject.controllerName;
  }
});

App.CountriesController = Ember.ObjectController.extend({
  needs: ['steps'],
  currentStep: Ember.computed.oneWay('controllers.steps.currentStep'),

  isExpanded: function() {
    return "countries" === this.get('currentStep');
  }.property('currentStep')
});

Steps.handlebars:

{{#each step in controller}}
  <div {{bind-attr class=":step controller.isExpanded:expanded"}}>
    {{view Ember.View templateName=step.templateName}}
  </div>
{{/each}}

我必须使用ObjectController for Countries控制器,因为使用ArrayController作为itemController不起作用

1 个答案:

答案 0 :(得分:4)

根据你设置用户界面的方式,我想我会在路由器中做这样的事情:

App.Router.map(function() {
  this.resource('wizard', function() {
    this.route('step1');
    this.route('step2');
    this.route('step3');
  });
});

然后,有一个wizard模板,如下所示:

{{#link-to 'wizard.step1'}}Step 1{{/link-to}}
<div {{bind-attr class='step1Expanded}}>{{outlet 'step1'}}</div>

{{#link-to 'wizard.step2'}}Step 2{{/link-to}}
<div {{bind-attr class='step2Expanded}}>{{outlet 'step2'}}</div>

{{#link-to 'wizard.step3'}}Step 3{{/link-to}}
<div {{bind-attr class='step3Expanded}}>{{outlet 'step3'}}</div>

然后,在每个step路由中,您需要覆盖renderTemplate,以便它在适当的插座中呈现,如下所示:

App.WizardStep1Route = Ember.Route.extend({
  renderTemplate: function() {
    this.render({outlet: 'step1'});
  }
});

最后,在WizardController内,您需要添加计算属性来处理应用于类的step1Expanded逻辑,以便您可以知道在任何给定时间显示哪一个。

所有这些都允许您在每个步骤中加载不同的模型,并且还允许您处理路径中的模型验证逻辑。例如,如果在步骤1和步骤2完成之前无法继续执行步骤3,则可以添加逻辑来处理step1和step2路径中的内容。