2013-12-17 9 views
27

Ich bin nicht sicher, ob die Art, wie ich es tue, korrekt ist, würde jeder Rat geschätzt werden.Wie umleiten, um zu zeigen, wenn bestimmte stateParam leer ist

Ich habe einen Restaurant Selector, aus dem der Benutzer ein Restaurant auswählen kann. Dann laden alle anderen Kind-Zustände Inhalte, die für das ausgewählte Restaurant spezifisch sind. Aber ich muss standardmäßig einen Kinderstatus auswählen, einschließlich eines Restaurants, das entweder basierend auf dem nächstgelegenen Standort des Nutzers oder auf Cookie-Daten ausgewählt wird, wenn diese zuvor ausgewählt wurden. Aber ich bin mir nicht sicher, wie ich standardmäßig zu einem Kind-Status umleiten kann, ohne die Restaurant-ID bereits zu kennen?

Eine Bastardversion meines Codes unten zu veranschaulichen.

app.config(function ($stateProvider, $urlRouterProvider) { 
$urlRouterProvider.otherwise("/restaurant/[some id based on cookie info]/our-food"); // if no id is set, then I want to get it from a cookie, but then how do i do the redirect? 

$stateProvider 
    .state('restaurant', { 
     url: '/restaurant/:restaurantId', 
     template: "<ui-view/>", 
     controller: function($state, $stateParams, Data, RestaurantService, $cookieStore) { 
      if(typeof $stateParams.restaurantId !== 'undefined') { 
            // get the restaurantID from the cookie 
          } 
     } 
    }) 
    .state('restaurant.our-food', { 
     url: '/our-food', 
     templateUrl: function($stateParams) { 
     return 'templates/food-food.html?restaurantId=' + $stateParams.restaurantId; 
     }, 
    controller: 'SubNavCtrl' 
    }) 
    .state('restaurant.glutenfree-vegetarian', { 
     url: '/glutenfree-vegetarian', 
     templateUrl: function($stateParams) { 
    return 'templates/food-vegetarian.html?restaurantId=' + $stateParams.restaurantId; 
     }, 
    controller: 'SubNavCtrl' 
    }) 

Ein Bild unten zeigen, was auf dem vorderen Ende passiert: www.merrywidowswine.com/ss.jpg

Antwort

37

Ich würde ein Ereignis, das jedes Mal, wenn die spezifischen Zustand öffnen abgefeuert wird.

überprüfen ihre doc aus: https://github.com/angular-ui/ui-router/wiki#onenter-and-onexit-callbacks

Also meine Vermutung ist, entweder so etwas wie dieses

1. onEnter Rückruf Restaurant Zustand (empfohlen)

$stateProvider.state("contacts", { 
    template: '<ui-view>', 
    resolve: ..., 
    controller: function($scope, title){ 
    }, 
    onEnter: function(){ 
    if(paramNotSet){ $state.go(...)} 
    } 
}); 

ich nie benutzt habe ein Ereignis als solches selbst, so dass du vielleicht etwas Gymnastik mit Entschlossenheit machen musst, aber ich glaube, dass dies die sauberste, am leichtesten zu verstehende und am besten wartbare Lösung ist.

2 Globale onStateChangeStart Ereignis Ein globales Ereignis (obwohl dies für jede Statusänderung gefeuert würde)

$rootScope.$on('$stateChangeStart', 
function(event, toState, toParams, fromState, fromParams){ ... //check cookie, change state etc ...}) 

3 In der Steuerung Alternativ Wenn Sie den Controller verwenden möchten, wie Sie begonnen tun.

Dies ist wahrscheinlich die schnellste Lösung in Bezug auf die Entwicklung, aber ich glaube, die Verwendung von Ereignissen ist sauberer und macht mehr verständlich Code.

Hinweis: Ich habe tatsächlich keinen dieser Code ausgeführt, so dass es möglicherweise nicht funktioniert, ist es nur Pseudo-Code, um Ihnen eine Vorstellung davon, wohin Sie gehen. Lass es mich wissen, wenn du Probleme hast.

BEARBEITEN: Ich bin mir natürlich nicht sicher, ob stateParams an den Controller weitergegeben werden. Möglicherweise müssen Sie Auflösung verwenden, um auf sie zuzugreifen.

EDIT: bis stateParams in onEnter Rückruf oder die Steuerung zugreifen, ich glaube, Sie lösen als solche verwenden:

resolve: { 
     checkParam: ['$state','$stateParams', '$cookieStore', function($state, $stateParams, $cookieStore) { 
//logic in here, what it returns can be accessed in callback or controller. 
     }] 

die ui-Router doc auf Entschlossenheit sehen für weitere Beispiele/bessere Erklärung

+0

Danke, das weist mich in die richtige Richtung, ich werde ein Spiel machen und sehen, ob ich alles in Gang bringen kann. Prost! –

+1

Das Problem (das ich hatte) mit Ihrer # 1-Lösung ist, dass alle auflösenden Eigenschaften aufgelöst werden, bevor 'onEnter' ausgeführt wird. Ich habe ein Problem mit GitHub gestartet: https://github.com/angular-ui/ui-router/issues/1102. Ich bin mir nicht sicher, ob es einen versteckten Haken zum Kurzschluss gibt, wenn die aufgelösten Parameter vor der Weiterleitung nicht aufgelöst werden sollen (wenn zum Beispiel die Route einen bestimmten Parameter benötigt). – Beez

+0

Anstelle von '$ state.transitionTo' wäre es vielleicht besser,' $ state.go' zu verwenden, wie hier [hier] angegeben (https://github.com/angular-ui/ui-router/wiki/Quick-Reference#). state-1) – Daniele

3

ich brauchte diese Funktion zu erhalten, so Details von @NicolasMoise auf die Antwort hinzuzufügen:

.state('restaurant', { 
    url: '/restaurant/:restaurantId', 
    template: "<ui-view/>", 
    onEnter: function ($state, $stateParams, $cookies) { 
     console.log($stateParams.restaurantId); 
     if (!$stateParams.restaurantId) { 
     $stateParams.restaurantId = $cookies.restaurantId; 
     $state.go('restaurant.restaurantID'); 
     } 
    }, 
}) 

I Ich habe den Cookie-Teil nicht getestet, aber die bedingte und die Statusänderung funktionierten.

Verwandte Themen