11

複数のステップを含むウィザードを作成する必要があります。各ステップでは、オプションを含むフォームが表示されます。ユーザーの選択に応じて、ウィザードは特定のステップに進み、ユーザー設定 (選択) をどこかに保存したままにします。

これらの設定はモデルに保存されず、モデル作成のステップにのみ関連します。

いくつかのコンテキストを提供するために、これの目標は次のとおりです。

  • ビジネスの営業時間についてユーザーにいくつか質問します。例:週末は開いていますか? 夏は違うの?.
  • これらの質問に対する回答に応じて、タイムテーブル モデルを作成するための最終フォームが表示されます。

問題は、Ember 内でこれを達成するための最良の方法はどれでしょうか?

これが私の–Ember初心者–の考えです。

  • ウィザードのステップごとにテンプレートを作成します。
  • 現在のステップを追跡します。どこ?コントローラ?ルート?
  • これらのテンプレートを に表示しoutletsます。現在のステップに従って動的にレンダリングする必要があります。これは私が完全に迷子になるところです。これを行う方法?各ステップに異なるルートを設定する必要がありますか?
  • コントローラーでユーザーの回答を追跡します。
  • ウィザードが完了したら、コントローラーに保存されているユーザー設定を読み取るフォーム テンプレートを読み込みます。

使用されているバージョン:

  • Ember.VERSION : 1.0.0-rc.1 application.js:9268
  • Handlebars.VERSION : 1.0.0-rc.3 application.js:9268
  • jQuery.バージョン: 1.9.1
4

3 に答える 3

12

あなたは正しい軌道に乗っているように聞こえます。

ウィザードのステップごとにテンプレートを作成します。

はい、それは良いスタートです。

現在のステップを追跡します。どこ?コントローラ?ルート?

コントローラーまたはルートのいずれかが機能します。Route は、各ステップでブックマーク可能な URL が必要な場合や、戻る/進むのが機能する場合に最も理にかなっていて、おそらく最も簡単なソリューションです。ルートを選択したと仮定します。

これらのテンプレートをアウトレットに表示し、現在のステップに従って動的にレンダリングする必要があります。これは私が完全に迷子になるところです。これを行う方法?各ステップに異なるルートを設定する必要がありますか?

各ステップはルートになるため、ember は適切なテンプレートを自動的にレンダリングします。

コントローラーでユーザーの回答を追跡します。

ウィザードが完了したら、コントローラーに保存されているユーザー設定を読み取るフォーム テンプレートを読み込みます。

「完了」は次のステップと考えてください。各ステップは、ユーザーの応答を記録するために使用される独自のコントローラーを取得します。最後のコントローラーは、ウィザードへの応答に基づいて動作をカスタマイズするために、「ニーズ」を使用して以前のコントローラーにアクセスします。

于 2013-03-13T13:34:35.370 に答える
8

私はこれが古いスレッドであり、おそらくOPには役立たないことを知っていますが、stackoverflowは何よりも多くの答えにつながります. これについてブログ記事を書きました。

この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'));
        }
    }
});

ルート値オブジェクトは、「ルートが routeVal.route と等しい場合、次のプロパティはこれらの値を持つ」という意味であると考えてください。次のボタンのテキストは「レビュー」で、前のボタンは非表示にする必要があります。」

そして最後に、リソース テンプレート:

<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>

form-wizard コンポーネントが何であったかについては、jsbin を確認できます (ルートに基づいて正しいステップでアクティブなクラスを維持する、Fuelux ウィザードの css をラップするだけです)。ウィザードの本文は、各サブルートのテンプレートです。次/前のボタンのテキストは、ルートに応じて変化し、トランジションも変化します (トランジションはウィザードの現在の状態に依存するため)。それは多かれ少なかれFSMです

于 2015-04-02T14:21:49.030 に答える
2

誰かが答えを必要とする場合に備えて、古い質問に答えます。

Ember.js を使用して、この マルチステップ フォーム (または複数の「ページ」) のようなものを 1 つのルートで使用できます。

これは 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
}

複数ページのフォームを簡単に実装するのに適しています。これに関する問題は、ビューの didInsertElement にフックする jQuery UI コードがあり、あるステップから別のステップに移動して戻ってきたときに機能することです (各ページには「次へ」ボタンと「前へ」ボタンがあります)。 didInsertElement で実行されたコードが元に戻されます。HTMLコードのチャンクが隠され、再表示されただけではないようです. リロードされたため、すべての効果がなくなりました。

于 2014-09-22T08:01:51.320 に答える