Como implementar aliases de caminho no roteador da interface do usuário

Eu estou tentando encontrar uma maneira de implementar alias de rota em Angular.js usando o ui-router .

Digamos que eu tenha um estado com o article/:articleId url article/:articleId e eu quero ter /articles/some-article-title redirecionado (internamente) para /article/76554 sem alterar a localização do navegador.

Isso poderia ser feito com o ui-router ?

I. Mapeamento de estado duplicado (reutilização do controlador, visualizações)

NOTA: Esta é uma resposta original, mostrando como resolver o problema com dois estados. Abaixo está outra abordagem, reagindo ao comentário de Geert

Há um plunker com exemplo de trabalho. Digamos que temos esses dois objects (em um servidor)

 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 gostaríamos de usar o URL como

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

Então podemos criar essas definições de estado:

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

Como podemos ver, o truque é que o Controller e o Template (templateUrl) são os mesmos. Nós apenas pedimos ao getById() para getById() ou getByTitle() . Uma vez resolvido, podemos trabalhar com o item devolvido …

O plunker com mais detalhes está aqui

II. Aliasing, com base na funcionalidade nativa UI-Router

Nota: Esta extensão reage ao comentário apropriado de Geert

Portanto, há uma maneira integrada / nativa do UI-Router para o alias de rota. É chamado

$ urlRouterProvider – .quando ()

Eu criei plunker de trabalho aqui . Em primeiro lugar, precisaremos de apenas uma definição de estado, mas sem quaisquer restrições à identificação.

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

Também temos que implementar algum mapeador, convertendo title para id (o alias mapper) . Isso seria novo método de serviço do artigo:

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

E agora o poder de $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; } ); 

É isso aí. Esta implementação simples pula erro, título errado … manipulação. Mas espera-se que isso seja implementado de qualquer forma … Confira aqui em ação