Cómo implementar alias de ruta en ui-enrutador

Estoy tratando de encontrar una forma de implementar alias de ruta en Angular.js usando ui-router .

Digamos que tengo un estado con el article/:articleId url article/:articleId y deseo que /articles/some-article-title redirija (internamente) a /article/76554 sin cambiar la ubicación del navegador.

¿Podría hacerse esto con ui-router ?

I. Duplicación del mapeo de estado (reutilización de controlador, vistas)

NOTA: Esta es la respuesta original, que muestra cómo resolver el problema con dos estados. A continuación hay otro enfoque, reactjsndo al comentario de Geert

Hay un plunker con un ejemplo de trabajo. Digamos que tenemos estos dos objetos (en un 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',}, ]; 

Y nos gustaría utilizar la URL como

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

Entonces podemos crear estas definiciones 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, el truco es que el controlador y la plantilla (templateUrl) son los mismos. Le pedimos al Service ArticleSvc que getById() o getByTitle() . Una vez resuelto, podemos trabajar con el artículo devuelto …

El plunker con más detalles está aquí

II. Aliasing, basado en la funcionalidad UI-Router nativa

Nota: esta extensión reactjs según el comentario apropiado de Geert

Por lo tanto, existe un modo UI-Router integrado / nativo para aliasing de ruta. Se llama

$ urlRouterProvider – .when ()

Creé un plunker de trabajo aquí . En primer lugar, solo necesitaremos una definición de estado, pero sin restricciones de ID.

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

También tenemos que implementar algún mapeador, convirtiendo el título en id (el mapeador de alias) . Ese sería el nuevo método de servicio del artículo:

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

Y ahora el 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; } ); 

Eso es. Esta sencilla implementación omite el error, el título incorrecto … manejo. Pero se espera que se implemente de todos modos … Compruébalo aquí en acción