2014-05-08 66 views
0

讓我先設置一些上下文; 我建立在角嚮導,具有這些特徵:

  • 嚮導的步驟是大;每一步都有自己的控制器/ $範圍/模板。
  • 嚮導中的步驟是動態的(步驟1的輸出決定下一步是step2a還是step2b)。
  • 當然,應該保留step-state。當從step2返回step1時,step1視圖中的數據應該仍然存在。

在我的實現中,我在代碼庫ui-router中找到了很多靈感。
基本上我的做法是:

  • 當去了一步,創造了這一步$範圍和使用$控制器服務創建控制器
  • $編譯步驟模板並把這個步驟 - 模板到步 - $範圍

這一切都很好。



但是,我懷疑我的實現要退回到嚮導中: 爲了達到這個目的,我爲每個已採取的步驟保留了一組step-$ scope對象。

每當(從第二步回到步驟1的實例),我退一步:

  • 查找了第一步的$範圍
  • 重新編譯$模板的第一步,它重新連接到對於第一步$範圍

這似乎是工作,但是:

  1. 爲什麼我就不能再用編譯/鏈接TEMPL從第1步吃完了?
    (這樣,我可以繼續引用編譯/鏈接的模板,而不是$ scopes)
  2. 這是重新編譯/重新鏈接正確的方法嗎?


感謝您的時間,
公園

+0

請分享更多的代碼... esp編譯的模板調用和編譯的模板示例 –

+0

嗨Dave,我在這個[jsfiddle]中創建了一個工作示例(http://jsfiddle.net/ ZZXQY/5 /)。 您感興趣的功能是「invokeStep」,其中存儲了步驟的模板/範圍;和「showStepInstance」,這個狀態被恢復。 – KoenJ

回答

1

我會用路由,使用的東西沿線

$routeProvider 
    .when('/wizard/:stepNr', {...}) 

(CF AngularJS文檔:https://docs.angularjs.org/api/ngRoute/service/ $路線#示例)

你的 「後退」 和 「下一步」 按鈕,將只是一個HREF像這樣:

<a href="#/wizard/{{scopeVarContainingNumberOfPrevStep}}">Prev</a> 
<a href="#/wizard/{{scopeVarContainingNumberOfNextStep}}">Next</a> 

所有步驟的範圍將有一個共同的$家長。所以,在去下一個步驟,你可以存儲重要的價值有:

$scope.$parent.stepData[currentStepNr] = $scope.stepData; 

每當回來了一步,未來的左腳步的範圍自動銷燬。所有你需要做的是

$scope.stepData = $scope.$parent.stepData[currentStepNr]; // load from parent scope into current scope 
delete $scope.$parent.stepData[currentStepNr]; // discard in the parent scope 

PS:其實父範圍適用於所有的步驟範圍是一個「特例」所以,你可能想使用一個服務,用於存儲步驟之間的數據,建議通過@Bixi

編輯:在的情況下,下一步的數量由外部網絡srevice確定,你可以做(​​假設一個簡單的HTTP調用)

$http.get('/your/service').success(function(responseData){ 
    /* grab nr of next step from responseData; 
     remember it and 
     use $location.$path to navigate to #/wizard/nextStep. */ 
    $location.$path('/wizard/' + varContainingNumberOfNextStep); 
}); 
+0

這種方法的問題是scopeVarContainingNumberOfNextStep應該是字體已知的。就我而言,Web服務調用是在「下一個」上執行的。此調用的結果決定了下一步是什麼。 – KoenJ

+0

這應該不是一個大問題。你可以做(​​假設一個簡單的http調用)'$ http.get('/ your/service').success(function(responseData){/ *從responseData獲取下一步的nr;記住它並使用$ location。$ path導航到#/ wizard/nextStep。* /});' – iPirat

1

首先,你是如何存儲你的數據?對於這種模式,最好的選擇是存儲步驟數據的服務。該服務將通過您的所有步驟(控制器)提供。

有關服務的更多信息:https://docs.angularjs.org/guide/services

接下來,你在談論兩個解決方案:

  • 存儲數據,讓角度構建從頭屏幕再次
  • 存儲完全編譯模板

第一個解決方案是角度標準行爲。爲了保持一個儘可能輕量級的DOM,angular會刪除先前的ng-view DOM元素,並用新元素(新路徑)替換它們。這裏沒有問題,這是角度的工作,它做得很好。

第二種解決方案是可能的。在我看來,存儲編譯的DOM將會是過度的,相反你可以讓它在瀏覽器中加載(但是通過CSS顯示/隱藏它的內容)......但是與方法1(重量級DOM)不同,它有一些缺點。

我認爲你應該讓角度構建你的步驟只使用存儲的數據。

+0

我將數據存儲在嚮導控件本身中,如[jsfiddle](http://jsfiddle.net/ZZXQY/5/)所示。您會注意到所有已採取步驟的信息均位於「takenSteps」字段中。 在此字段中,存儲範圍和模板。當需要恢復這些步驟時,將根據此範圍重新編譯模板。 我認爲這很符合你的第一個選擇,除了我沒有使用服務來實現這一點,而是讓嚮導控制它自己來處理這個問題。 – KoenJ

+0

你的整個代碼看起來非常複雜,也許你可以使用更多的內置函數的角度,就像我在我的第一個選項中解釋的那樣......但也許在你的情況下需要更多的靈活性。這取決於你現在;) –

+0

它確實變得相當複雜;我幾乎覺得我正在創建自己的路由器。我會重新考慮並看看是否有另一種方法,即利用基本的角度概念。感謝您的建議。 – KoenJ

0

爲什麼不只是有帶有一些步驟標誌和mak的父控制器e使用ngInclude功能創建新的子範圍?

mod.controller('WizardParentCtrl', function() { 
    this.step = '1'; 
}) 

外部HTML:

<div ng-controller="WizardParentCtrl as WizardParent"> 
    <div ng-include="'steps/'+WizardParent.step+'.html'"></div> 
</div> 

內HTML:

<div ng-controller="Step1Ctrl as Step1"> 
... 
</div> 

WizardParent將在通過範圍繼承子控制器訪問,並可以以挽救與它進行通信數據或更改步驟。