Ember.js - 创建一个多步骤向导 - 如何?

Man*_*era 11 model-view-controller ember.js

我需要创建一个包含多个步骤的向导.每个步骤都将显示一个带有选项的表单,根据用户的选择,向导应该转到某个步骤,并保持用户首选项(选项)存储在某个位置.

这些首选项不会保存在模型中,它们仅与模型创建步骤相关.

为了给出一些背景,这个目标是:

  • 向用户提出有关其业务营业时间的几个问题.例如:周末开放吗?,夏天不一样吗?.
  • 根据这些问题的答案,将显示最终表格以创建时间表模型.

问题是,这将是在Ember内部实现这一目标的最佳方式吗?

这是我的--Ember新手 - 想法:

  • 为每个向导步骤创建一个模板.
  • 跟踪当前步骤.哪里?控制器?路线?
  • 显示这些模板outlets,应根据当前步骤动态呈现.这是我完全迷失的地方.这该怎么做?每个步骤应该有不同的路线吗?
  • 跟踪控制器中的用户答案.
  • 完成向导后,加载表单模板,该模板将读取存储在控制器中的用户首选项.

正在使用的版本:

  • Ember.VERSION:1.0.0-rc.1 application.js:9268
  • Handlebars.VERSION:1.0.0-rc.3 application.js:9268
  • jQuery.VERSION:1.9.1

Mik*_*tti 12

听起来你走在正确的轨道上.

为每个向导步骤创建一个模板.

是的,这是一个好的开始.

跟踪当前步骤.哪里?控制器?路线?

控制器或路线都可以工作.如果您希望每个步骤都有可收藏的网址以及后退/前进工作,那么路线最有意义,可能是最直接的解决方案.假设你选择了路线.

将这些模板显示在出口中,应根据当前步骤动态呈现.这是我完全迷失的地方.这该怎么做?每个步骤应该有不同的路线吗?

由于每个步骤都是一个路径,因此ember将自动渲染适当的模板.

跟踪控制器中的用户答案.

完成向导后,加载表单模板,该模板将读取存储在控制器中的用户首选项.

将"完成"视为另一个步骤.每个步骤都有自己的控制器,用于记录用户响应.最后一个控制器使用"需求"来访问早期的控制器,以便根据对向导的响应自定义行为.


mis*_*nry 8

我知道这是一个旧线程,可能无法帮助OP,但stackoverflow会导致更多答案.我刚刚写了一篇博文.

看看这个JSBin,看看我做了什么.我在这里总结一下.

模板中每步的路径:

Router.map(function() {
  this.resource('wizard', function(){
    this.route('index');
    this.route('review');
    this.route('complete');
  });
});
Run Code Online (Sandbox Code Playgroud)

自定义计算属性,在路由更改时更改值(在这种情况下,向导的步骤更改时)

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];
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

一个route-value对象:

export default Ember.Object.extend({
    route: null
    //all other props can be added dynamically
});
Run Code Online (Sandbox Code Playgroud)

控制器mixin用于了解当前路线:

export default Ember.Mixin.create({  
    needs: ['application'],
    currentPath: Ember.computed.alias("controllers.application.currentPath")

});
Run Code Online (Sandbox Code Playgroud)

资源控制器:

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'));
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

将路由值对象视为含义,"当路由等于routeVal.route时,以下属性将具有这些值"例如"当当前活动路由为'wizard.index'时,下一个转换为'wizard.review',下一个按钮文本是'Review',前一个按钮应该隐藏,等等"

最后,您的资源模板:

<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>
Run Code Online (Sandbox Code Playgroud)

您可以查看jsbin以了解表单向导组件的内容(只是围绕使用Fuelux向导的css进行包装,使基于路由的活动类保持正确的步骤).向导的主体是每个子路径的模板.下一个/上一个按钮的文本根据路径而改变,它们的转换也是如此(因为转换取决于向导的当前状态).它或多或少是一个FSM