2014-07-26 14 views
9

Gibt es trotzdem einen Standardparameter für jede Route mit dem Angular UI Router?Angular UI Router - Standardparameter

Meine App wird über den Kontext einer anderen Anwendung eingegeben, indem Sie einen Benutzer auswählen und dann zu meiner Anwendung navigieren. Die URL in meiner Anwendung wird die Benutzer-ID in der URL immer so, dass die Menschen die URL Lesezeichen können, mailen Sie es, etc. So, wie Sie rund um navigieren, folgt die URL immer ein Schema:

#/{userId}/view/... 
#/{userId}/edit/... 

etc .

Diese userId wird für einen Benutzer innerhalb der App immer gleich sein für jede Route, zu der sie gehen. Wenn sie sich abmelden, zurück zur Haupt-App gehen, einen neuen Benutzer auswählen und zu meiner App zurückkehren, wird sich diese userId ändern, wird aber für jede Route den gleichen Wert haben.

Gibt es trotzdem einen Wert von einem Service/Fabrik zu lesen und dann in jede Route zu stecken?

EDIT:

Ich sollte erwähnen, ich möchte diesen Parameter explizit auf jeder Strecke, um zu vermeiden, wenn ich in einen Zustand zu navigieren. Ich möchte zum Beispiel nicht jedes Mal, wenn ich zu einem neuen Zustand navigiere, machen müssen. Diese userId wird sich nie im Kontext meiner Anwendung ändern.

Erneut bearbeiten:

Ich ging eigentlich um diese eine andere Art und Weise die Anforderungen in Bezug auf nicht ‚userId‘ manuell zu jeder Route senden hat. Anstatt eine Direktive zu verwenden, habe ich einen $ provider.decorator verwendet, um diese Funktionalität der 'go' Methode hinzuzufügen. Ich habe unten eine Antwort hinzugefügt, was ich getan habe.

Antwort

7

Sie können eine abstrakte Mutter Zustand, aus dem erklären Kind Staaten erben:

$stateProvider 
    .state('user', { 
    url: '/:userid', 
    abstract: true, 
    resolve: 
     // assuming some kind of User resource factory 
     currentUser: function($stateParams, User) { 
     return User.get($stateParams.userid); 
     } 
    } 
    }) 
    .state('user.view', { 
    url: '/view', // actual url /:userid/view 
    controller: function($scope, currentUser) { 
     // currentUser resource available 
    } 
    }); 
    .state('user.edit', { 
    url: '/edit', // actual url /:userid/edit 
    controller: function($scope, currentUser) { 
     // currentUser resource available 
    } 
    }); 

In Bezug auf die in einen Zustand zu navigieren, müssen Sie in den gewünschten Benutzer übergeben:

$state.go('user.view', {userid: 'myuserid'}); 

Als Folglich kann es sinnvoll sein, eine Art .go() Wrapper-Methode für Ihren currentUser-Dienst zu erstellen, sodass Sie die Benutzer-ID nicht jedes Mal angeben müssen.

UPDATE:

angular.module('app') 
    .directive('userSref', function($state) {    
    return function(scope, elem, attrs) { 
     var state = 'user.' + attrs.userSref; 

     elem.bind('click', function() { 
     $state.go(state, {userid: $state.params.userid}); 
     });   

     scope.$on('$destroy', function() { 
     elem.unbind('click'); 
     }); 
    }; 
    }); 

Dann jegliche zukünftigen Links auf benutzerbasierte Zustände können so geschehen:

das Problem in Ihrem bearbeiten geschrieben Um dem entgegenzuwirken, können Sie eine Richtlinie wie folgt vorstellen könnte mit:

<a user-sref="view">View User</a> 
+0

LOL, das ist im Grunde, was ich gesagt habe, ohne den abstrakten Zustand :) Dies ist wünschenswert, wenn die App nicht die oberste Ebene Zustand, außer die Bereitstellung eines "Basis" Zustand zu übernehmen View Templates, Controller-Funktionalität und Parameter benötigt. –

+0

Wenn Sie den Status auf oberster Ebene benötigen, meinen Sie damit einen Status, der in der '/: userid'-URL umgestellt werden kann? Dies ist immer noch mit einem abstrakten Zustand möglich. Ich finde den abstrakten Zustand in Anwendungsfällen wie dem, der in der Frage vorgestellt wird, ideal, da er als Basiszustand dient, wie du sagst. – scarlz

+0

Eine Sache, die ich vermeiden möchte, ist, dass ich die userId an jede Route weitergeben muss. Ich möchte, dass es automatisch von einem Dienst oder etwas angeschlossen wird. Ich habe diesen Kommentar zu meiner ursprünglichen Frage hinzugefügt – sma

-1

Sie können die Funktionen "Nested States" und "Resolves" des UI-Routers verwenden, um eine Hierarchie von Zuständen in Ihrer App zu erstellen. Sie definieren einen Zustand der obersten Ebene, der die userId löst. Definieren Sie dann eine beliebige Anzahl von untergeordneten Zuständen, und diese erben automatisch die "aufgelöste" userId.

Check out this page of the documentation, insbesondere der Abschnitt mit dem Titel "Wichtige $ stateParams Gotcha". Ich werde die zwei Code-Snippets von dieser Seite hier einfügen.

falsche Methode:

$stateProvider.state('contacts.detail', { 
    url: '/contacts/:contactId', 
    controller: function($stateParams){ 
     $stateParams.contactId //*** Exists! ***// 
    } 
}).state('contacts.detail.subitem', { 
    url: '/item/:itemId', 
    controller: function($stateParams){ 
     $stateParams.contactId //*** Watch Out! DOESN'T EXIST!! ***// 
     $stateParams.itemId //*** Exists! ***// 
    } 
}) 

richtige Methode mit "Entschlüssen":

$stateProvider.state('contacts.detail', { 
    url: '/contacts/:contactId', 
    controller: function($stateParams){ 
     $stateParams.contactId //*** Exists! ***// 
    }, 
    resolve:{ 
     contactId: ['$stateParams', function($stateParams){ 
      return $stateParams.contactId; 
     }] 
    } 
}).state('contacts.detail.subitem', { 
    url: '/item/:itemId', 
    controller: function($stateParams, contactId){ 
     contactId //*** Exists! ***// 
     $stateParams.itemId //*** Exists! ***// 
    } 
}) 

Da die "ContactID" Parameter vom übergeordneten Zustand behoben ist, wird das Kind Zustand, erbt.

+0

Ich mag diese Lösung, danke für die Hilfe. (Ich akzeptierte die andere Antwort wegen der Richtlinie Idee). – sma

3

Anstatt eine Richtlinie des Schreibens, dass die auto-Senden von Benutzer-ID behandelt, habe ich $provide.decorator wie folgt:

app.config(['$provide', 
    function($provide) { 
     $provide.decorator('$state', function($delegate, UserService) { 

      // Save off delegate to use 'state' locally 
      var state = $delegate; 

      // Save off reference to original state.go 
      state.baseGo = state.go; 

      // Decorate the original 'go' to always plug in the userID 
      var go = function(to, params, options) { 

       params.userID = UserService.userID; 

       // Invoke the original go 
       this.baseGo(to, params, options); 
      }; 

      // assign new 'go', decorating the old 'go' 
      state.go = go; 

      return $delegate; 
     }); 
    } 
]); 

ich die Idee von diesem Posten bekam:

Changing the default behavior of $state.go() in ui.router to reload by default

+0

Das ist super @sma! Vielen Dank – Maxime

Verwandte Themen