Come implementare alias del percorso in ui-router

Sto cercando di trovare un modo per implementare alias di route in Angular.js utilizzando ui-router .

Diciamo che ho uno stato con l’ article/:articleId url article/:articleId e voglio avere /articles/some-article-title reindirizzato (internamente) a /article/76554 senza cambiare la posizione del browser.

Questo potrebbe essere fatto con ui-router ?

I. Mappatura dello stato raddoppiata (riutilizzo del controller, viste)

NOTA: Questa è la risposta originale, che mostra come risolvere il problema con due stati. Di seguito è riportato un altro approccio, reagendo al commento di Geert

C’è un plunker con un esempio funzionante. Supponiamo di avere questi due oggetti (su un server)

 var articles = [ {ID: 1, Title : 'The cool one', Content : 'The content of the cool one',}, {ID: 2, Title : 'The poor one', Content : 'The content of the poor one',}, ]; 

E vorremmo usare l’URL come

 // by ID ../article/1 ../article/2 // by Title ../article/The-cool-one ../article/The-poor-one 

Quindi possiamo creare queste definizioni di stato:

 // the detail state with ID .state('articles.detail', { url: "/{ID:[0-9]{1,8}}", templateUrl: 'article.tpl.html', resolve : { item : function(ArticleSvc, $stateParams) { return ArticleSvc.getById($stateParams.ID); }, }, controller:['$scope','$state','item', function ( $scope , $state , item){ $scope.article = item; }], }) // the title state, expecting the Title to be passed .state('articles.title', { url: "/{Title:[0-9a-zA-Z\-]*}", templateUrl: 'article.tpl.html', resolve : { item : function(ArticleSvc, $stateParams) { return ArticleSvc.getByTitle($stateParams.Title); }, }, controller:['$scope','$state','item', function ( $scope , $state , item){ $scope.article = item; }], }) 

Come possiamo vedere, il trucco è che il Controller e il Template (templateUrl) sono gli stessi. Chiediamo semplicemente al Service ArticleSvc di getById() o getByTitle() . Una volta risolto, possiamo lavorare con l’articolo restituito …

Il plunker con maggiori dettagli è qui

II. Aliasing, basato sulla funzionalità del UI-Router nativo

Nota: questa estensione reagisce al commento appropriato di Geert

Quindi, esiste un modo integrato / nativo del UI-Router per l’aliasing del percorso. È chiamato

$ urlRouterProvider – .when ()

Ho creato un plunker funzionante qui . In primo luogo, avremo bisogno solo di una definizione di stato, ma senza alcuna restrizione sull’ID.

 .state('articles.detail', { //url: "/{ID:[0-9]{1,8}}", url: "/{ID}", 

Dobbiamo anche implementare alcuni mapper, convertendo il titolo in id (l’alias mapper) . Quello sarebbe il nuovo metodo di servizio dell’articolo:

 var getIdByTitle = function(title){ // some how get the ID for a Title ... } 

E ora il potere di $urlRouterProvider.when()

  $urlRouterProvider.when(/article\/[a-zA-Z\-]+/, function($match, $state, ArticleSvc) { // get the Title var title = $match.input.split('article/')[1]; // get some promise resolving that title // converting it into ID var promiseId = ArticleSvc.getIdByTitle(title); promiseId.then(function(id){ // once ID is recieved... we can go to the detail $state.go('articles.detail', { ID: id}, {location: false}); }) // essential part! this will instruct UI-Router, // that we did it... no need to resolve state anymore return true; } ); 

Questo è tutto. Questa semplice implementazione salta l’errore, il titolo errato … la gestione. Ma dovrebbe essere comunque implementato … Controllalo qui in azione