我从 MartinElvar 的 excellent answer 开始,但由于我需要在向导的每一页上验证一个表单,所以最终换了一个地方。通过使向导的每个页面成为自己的组件,您可以轻松地限制每个页面的验证。
从控制器上的步骤列表开始:
// app/controllers/wizard.js
export default Ember.Controller.extend({
steps: ['stepOne', 'stepTwo', 'stepThree'],
currentStep: undefined
});
然后确保无论何时输入您的控制器,都会让用户跳到第一步:
// app/routes/wizard.js
export default Ember.Route.extend({
setupController (controller, model) {
controller.set('currentStep', controller.get('steps').get('firstObject');
this._super(controller, model);
}
});
现在您可以返回控制器并添加一些更通用的下一步/返回/取消步骤:
// app/controller/wizard.js
export default Ember.Controller.extend({
steps: ['step-one', 'step-two', 'step-three'],
currentStep: undefined,
actions: {
next () {
let steps = this.get('steps'),
index = steps.indexOf(this.get('currentStep'));
this.set('currentStep', steps[index + 1]);
},
back () {
let steps = this.get('steps'),
index = steps.indexOf(this.get('currentStep'));
this.set('currentStep', steps.get(index - 1));
},
cancel () {
this.transitionToRoute('somewhere-else');
},
finish () {
this.transitionToRoute('wizard-finished');
}
}
});
现在为您的向导页面定义一个组件。这里的技巧是定义与控制器中列出的每个步骤具有相同名称的每个组件。 (这允许我们稍后使用组件助手。)这部分允许您在向导的每个页面上执行表单验证。例如,使用ember-cli-simple-validation:
// app/components/step-one.js
import {ValidationMixin, validate} from 'ember-cli-simple-validation/mixins/validate';
export default Ember.Component.extend(ValidationMixin, {
...
thingValidation: validate('model.thing'),
actions: {
next () {
this.set('submitted', true);
if (this.get('valid')) {
this.sendAction('next');
}
},
cancel () {
this.sendAction('cancel');
}
}
});
最后,路线的模板变得直截了当:
// app/templates/wizard.hbs
{{component currentStep model=model
next="next" back="back" cancel="cancel" finish="finish"}}
每个组件都获得对控制器模型的引用,并在步骤中添加所需的数据。这种方法对我来说非常灵活:它允许您在向导的每个阶段做任何必要的疯狂事情(例如与硬件交互并等待它响应)。