2013-03-13 12 views
11

Birden çok adımla sihirbaz oluşturmalıyım. Her adım, seçenekler içeren bir form gösterecek ve kullanıcı seçimlerine bağlı olarak, sihirbaz belirli bir aşamaya gitmeli ve kullanıcı tercihlerini (seçimleri) bir yerde saklamalı.Ember.js - Çok adımlı bir sihirbaz oluşturma - Nasıl yapılır?

Bu tercihler modele kaydedilmez, yalnızca model oluşturma adımıyla ilgilidir.

bazı bağlamda vermek amacıyla, bu hedefi:

  • kullanıcıya onun iş açık olduğu saatler ile ilgili bir kaç soru olun. Örneğin: Hafta sonları açık mı?, Yaz aylarında farklı mıdır?.
  • Bu soruların cevaplarına göre, zaman çizelgesi (modelleri) modelini oluşturmak için son bir form görüntülenecektir.

Bu, Ember'in içinde başarmanın en iyi yolu hangisidir?

  • her sihirbaz adım için bir şablon oluşturun: Burada

    benim -Ember newbie- düşüncelerdir.
  • Geçerli adımı takip edin. Nerede? Denetleyici? Rota?
  • Ekran şimdiki aşamasına göre dinamik olarak oluşturulması gereken outlets içine bu şablonlar. Burası tamamen kaybolduğum yer. Bu nasıl yapılır? Her adımın farklı bir yolu var mı, olmamalı mı? kontrolörü kullanıcı cevapları
  • takip edin.
  • Sihirbaz tamamlandığında, denetleyicide saklanan kullanıcı tercihlerini okuyacak form şablonunu yükleyin.

Versiyonlar kullanılır:

  • Ember.VERSION: 1.0.0-rc.1 application.js: 9268
  • Handlebars.VERSION: 1.0.0-rc.3 uygulaması js: 9268
  • jQuery.VERSION: doğru yolda olduğu gibi 1.9.1
+0

Zaten bazı fikirlerin var gibi görünüyor. Neden ilk önce onları uygulamaya çalışmıyorum? Sorununuzu çözmek için çaba gösterdiğinizde, insanların size yardımcı olma olasılıklarının daha yüksek olduğunu düşünüyorum. – DaMainBoss

+0

http://stackoverflow.com/questions/14701856/ember-js-wizard-control <= Bu yardımcı olabilir;) JSBin'de bir şeyler başlatabilirsiniz. – DaMainBoss

+0

@DaMainBoss aslında birkaç saat çalışıyorum ve hala bu anı deniyorum. Denetleyiciden 'connectOutlet' ile başladı ve denetleyicilerin' connectOutlet' yöntemine sahip olmadığını, ardından görüntüye taşıdığını ve daha sonra rotalarla denendiğini söyledi. Bütün niyetler bir noktada başarısız oldu, bu yüzden mimarlık yönergelerini soruyorum ve gerçek kod örneklerini değil, çünkü karanlıkta bıçakladığımı hissediyorum. Ayrıca, zaten bağlantılı bir soru olduğunu daha önce de görmüştüm ama ilk bakışta göründüğüm gibi bu soru ile ilgili değil. –

cevap

12

geliyor.

her sihirbaz adım için bir şablon oluşturun.

Evet, bu iyi bir başlangıçtır. Geçerli adımın

takip edin. Nerede? Denetleyici? Rota?

Ya kontrolör veya rota çalışacak.Her adımda ve geri/ileriye doğru iş için adreslenebilir URL'ler istiyorsanız ve muhtemelen en basit çözüm ise rota en mantıklı. Rotayı seçtiğinizi varsayalım.

Bu şablonları, geçerli adıma göre dinamik olarak oluşturulması gereken çıkışlar halinde görüntüleyin. Burası tamamen kaybolduğum yer. Bu nasıl yapılır? Her adımın farklı bir yolu var mı, olmamalı mı? Her bir adım bir rota olacağından, imber uygun şablonun otomatik olarak oluşturulmasına özen gösterecektir.

Kullanıcı yanıtlarını denetleyicide takip edin.

Sihirbaz tamamlandığında, denetleyicide saklanan kullanıcı tercihlerini okuyacak form şablonunu yükleyin.

"Bitti" yi başka bir adım olarak düşünün. Her adım, kullanıcı yanıtlarını kaydetmek için kullanılan kendi denetleyicisini alır. Son denetleyici, sihirbaza verilen yanıtlara göre davranışı özelleştirmek için önceki denetleyicilere erişmek için "gereksinimler" kullanır.

+1

fakat bir sonraki adıma geçmeden önce verileri kaydetmek istediğinizde nasıl takip edebilirsiniz? – Nininea

2

Kişinin bazı yanıtlara ihtiyacı olması durumunda eski bir soruyu yanıtlama. Bunu uygulandığında

Bunun için 1 rotayı kullanılarak görünür veya gizli her adımı/sayfayı kullanan bu Multi-step form (or multiple "pages") in one route using Ember.js

gibi bir şey kullanabilirsiniz {{#if}} Nino'nın soruya cevap vermek için ben bir nesne vardı denetleyicimde form alanlarının tüm değerlerini izleyerek ve sonraki tıklattığımda güncelleştirerek. Gönderdiğiniz nerede son sayfaya geldiğinizde, sadece çok sayfalı formunun basit uygulanması için iyi bu

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 
} 

gibi kontrolörün göndermek fonksiyonu içine bu nesneyi takabilirsiniz. Sorun şu ki ben görünümün didInsertElement içine kanca jQuery UI kodu var ve sadece bir adımdan diğerine gitmek ve geri geldiğinde çalışır (her sayfa 'next' ve 'prev' düğmeleri vardır), bunu bulmak didInsertElement koşulan kod ne olursa olsun. Bu html kodunun öbürü sadece gizli ve yeniden gösterilmemiş gibi. Yeniden yüklendi ve böylece tüm efektler gitti.

8

Bu eski bir iş parçacığı biliyorum ve muhtemelen OP'ye yardımcı olmayacaktır, ancak stackoverflow başka bir şeyden daha fazla yanıt alır. Bu konuda sadece blog post yazdım.

Yaptığım şeyi görmek için bu JSBin adresine bakın. Burada özetleyeceğim.şablonda adım başına

Rota:

Router.map(function() { 
    this.resource('wizard', function(){ 
    this.route('index'); 
    this.route('review'); 
    this.route('complete'); 
    }); 
}); 

Özel hesaplanmış mülk yolları değiştiğinde değerlerini değiştirir (bu durumda zaman sihirbaz değişikliklerin adımlar)

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]; 
      } 
     } 
    }); 
} 

A route-value nesne:

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

Üründen haberdar olmak için bir denetleyici mikseri kira rota:

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

}); 

kaynak kontrolörü:

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

anlam olarak rota değeri nesnenin Think, "rota routeVal.route eşittir, aşağıdaki özellikler sahip olacak bu değerler" örneğin " şu anda aktif olan rota 'wizard.index' dir, bir sonraki geçiş 'wizard.review', bir sonraki düğme metni 'Review', önceki butonun gizlenmesi gerekir, vs "

Ve son olarak, kaynak şablonunuz:

Form-sihirbaz bileşeninin ne olduğu için jsbin'e bakabilirsiniz (yalnızca, etkin sınıfı etkin rotada tutarak, rotaya göre doğru adımı koruyan). Sihirbazın gövdesi, her bir alt adımın şablonudır. Bir sonraki/önceki düğmenin metni, geçişler gibi geçişe bağlı olarak değişir (geçiş, sihirbazın geçerli durumuna bağlıdır). Daha fazla veya daha az bir FSM

+1

+1 Çok yardımsever! Başvurulan blog yazısı ve JS Bin arasında, bunu bir CLI projesinde bir araya getirmeyi başardım. Zor kısım, "Özel Bilgisayar Mülkiyeti" ni içeriyordu. İçe aktarılması gerektiği gibi yazılmış, ancak ham işlevi aldım ve denetleyicinin tanımının hemen üstüne düştüm. Çok teşekkürler! – Jim

+0

Pek çok yerde bu işlevi kullanıyorum, bu yüzden hesaplanan özellikler için 'macros.js' adlı bir kullanim sınıfı kullanıyorum. Bir işlevi içe aktarma sözdizimi biraz farklı olduğundan cevabı bu şekilde güncelleyeceğim. '{Fn_name}' işlevini kullanıyorsunuz – sunrize920

İlgili konular