我需要创建一个包含多个步骤的向导。每个步骤都会显示一个带有选项的表单,根据用户的选择,向导应该转到某个步骤,同时保持用户首选项(选项)存储在某个地方。
这些首选项不会保存在模型中,它们仅与模型创建步骤相关。
为了给出一些背景信息,其目标是:
问题是,哪个是在Ember中完成这个的最好方法?
以下是我的-Ember新手 - 想法:
outlets
中,应根据当前步骤动态呈现。 这是我完全迷失的地方。这该怎么做?每个步骤是否应该有不同的路线? 正在使用的版本:
答案 0 :(得分:12)
听起来你走在正确的轨道上。
为每个向导步骤创建一个模板。
是的,这是一个好的开始。
跟踪当前步骤。哪里?控制器?路线?
控制器或路线都可以使用。如果您希望每个步骤都有可收藏的网址以及后退/前进工作,那么路线最有意义,可能是最直接的解决方案。假设你选择了路线。
将这些模板显示在插座中,应根据当前步骤动态呈现。这是我完全迷失的地方。这该怎么做?每个步骤是否应该有不同的路线?
由于每个步骤都是一个路径,因此ember将自动渲染适当的模板。
在控制器中跟踪用户答案。
向导完成后,加载表单模板,该模板将读取存储在控制器中的用户首选项。
将“完成”视为另一个步骤。每个步骤都有自己的控制器,用于记录用户响应。最后一个控制器使用“需求”来访问早期的控制器,以便根据对向导的响应自定义行为。
答案 1 :(得分:8)
我知道这是一个旧线程,可能不会帮助OP,但stackoverflow会导致更多的答案。我刚刚写了blog post。
看看这个JSBin,看看我做了什么。我在这里总结一下。
模板中的每步路径:
Router.map(function() {
this.resource('wizard', function(){
this.route('index');
this.route('review');
this.route('complete');
});
});
自定义计算属性,在路由更改时更改值(在这种情况下,向导的步骤更改时)
import Ember from 'ember';
var get = Ember.get;
var computed = Ember.computed;
export function routeVal(routeVals, prop){
return computed('currentPath', function(){
var currentRoute = get(this, 'currentPath');
var routeValues = get(this, routeVals);
for (var i = 0; i < routeValues.length; i++) {
if (routeValues[i].route === currentRoute) {
return routeValues[i][prop];
}
}
});
}
route-value
对象:
export default Ember.Object.extend({
route: null
//all other props can be added dynamically
});
控制器mixin以了解当前路线:
export default Ember.Mixin.create({
needs: ['application'],
currentPath: Ember.computed.alias("controllers.application.currentPath")
});
资源控制器:
import CurrentRouteAware from 'path/to/mixin';
import {routeVal} from 'app_name/utils/macros';
export default Ember.Controller.extend(CurrentRouteAware, {
routeValues: [
RouteVal.create({
route: 'wizard.index',
step: 'Create',
next: 'Review',
nextTransition: 'wizard.review',
prevTransition: 'wizard.index',
showNext: true,
showPrev: false
}),
RouteVal.create({
route: 'wizard.review',
step: 'Review',
next: 'Complete',
prev: 'Create',
nextTransition: 'wizard.complete',
prevTransition: 'wizard.index',
showNext: true,
showPrev: true
}),
RouteVal.create({
route: 'wizard.complete',
step: 'Complete',
next: 'Make Another',
prev: 'Review',
nextTransition: 'wizard.complete',
prevTransition: 'wizard.review',
showNext: false,
showPrev: true
})
],
nextButton: routeVal('routeValues', 'next'),
prevButton: routeVal('routeValues', 'prev'),
nextTransition: routeVal('routeValues', 'nextTransition'),
showButtons: routeVal('routeValues', 'showButtons'),
prevTransition: routeVal('routeValues', 'prevTransition'),
showNext: routeVal('routeValues', 'showNext'),
showPrev: routeVal('routeValues', 'showPrev'),
actions: {
next: function(){
this.transitionToRoute(this.get('nextTransition'));
},
prev: function(){
this.transitionToRoute(this.get('prevTransition'));
}
}
});
将路线值对象视为含义,&#34;当路线等于routeVal.route时,以下属性将具有这些值&#34;例如&#34;当前活动的路线是&#39; wizard.index&#39;下一个转换是&#39; wizard.review&#39;,下一个按钮文字是&#39;评论&#39;,前一个按钮应该被隐藏,等等#34;
最后,您的资源模板:
<div class="wizard" id="wizardIllustration">
{{form-wizard steps=routeValues currentPath=currentPath}}
<div class="actions">
{{#if showPrev}}
<button type="button" {{action 'prev'}}class="btn btn-default btn-prev"><span class="glyphicon glyphicon-arrow-left"></span>{{prevButton}}</button>
{{/if}}
{{#if showNext}}
<button {{action 'next'}}type="button" class="btn btn-default btn-next" >{{nextButton}}<span class="glyphicon glyphicon-arrow-right"></span></button>
{{/if}}
</div>
<div class="step-content">
{{outlet}}
</div>
</div>
您可以查看jsbin表单向导组件的内容(只是围绕使用Fuelux向导的css进行包装,使基于路由的活动类保持正确的步骤)。向导的主体是每个子路径的模板。下一个/上一个按钮的文本根据路径而改变,它们的转换也是如此(因为转换取决于向导的当前状态)。它或多或少是一个FSM
答案 2 :(得分:2)
在有人需要答案的情况下回答旧问题。
你可以使用这样的东西 Multi-step form (or multiple "pages") in one route using Ember.js
这利用了1条路线,并使用{{#if}}显示或隐藏了每个步骤/页面 要回答Nino的问题,当我实现这个问题时,我的控制器中有一个对象跟踪表单字段的所有值,并在我单击下一步时更新它。当你到达你提交的最后一页时,你可以简单地将这个对象插入控制器的提交功能,如下所示
submitSurvey: function() {
var survey = this.store.createRecord('survey', this.get('surveyObj'));
// surveyObj contains all the form field's values that you've been
// keeping track of everytime you go from one step to another
survey.save();
this.transitionToRoute('somewhere'); // go somewhere after submitting the form
this.set('firstPage', true); // make first page the page to show
this.set('lastPage', false);
this.init();
// constructor's init contains code that empties all the form fields alternatively
// you can create a separate function instead of using init
}
适用于简单实现多页表单。我遇到的问题是我有jQuery UI代码挂钩到视图的didInsertElement,它只是当我从一个步骤走到另一个并返回(每个页面有'next'和'prev'按钮)时,我发现无论在didInsertElement上运行的代码都被撤消。这就像html代码的大块不仅仅是隐藏和重新显示。它被重新加载,因此所有效果都消失了。