【问题标题】:How to implement path aliases in ui-router如何在 ui-router 中实现路径别名
【发布时间】:2018-01-18 16:58:10
【问题描述】:

我正在尝试找到一种方法来使用ui-router 在 Angular.js 中实现路由别名。

假设我有一个带有 url article/:articleId 的状态,我希望在不更改浏览器位置的情况下将 /articles/some-article-title 重定向(内部)到 /article/76554

这可以用ui-router 完成吗?

【问题讨论】:

    标签: angularjs angular-ui angular-ui-router


    【解决方案1】:

    我。双重状态映射(控制器、视图的重用)

    注意:这是原始答案,展示了如何解决两种状态的问题。下面是另一种方法,对Geert

    的评论做出反应

    有一个带有工作示例的plunker。假设我们有这两个对象(在服务器上)

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

    我们想使用 URL 作为

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

    然后我们可以创建这个状态定义:

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

    正如我们所见,诀窍在于 ControllerTemplate (templateUrl) 是相同的。我们只需询问服务ArticleSvcgetById()getByTitle()。解决后,我们可以处理退回的项目...

    更详细的plunker是here

    二。别名,基于原生 UI-Router 功能

    注意:此扩展会对 Geert 适当的评论做出反应

    所以,有一个UI-Router 内置/原生方式用于路由别名。它被称为

    $urlRouterProvider - .when()

    我创建了工作plunker here。首先,我们只需要一个状态定义,但对 ID 没有任何限制。

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

    我们还必须实现一些映射器,将标题转换为 id (别名映射器)。那将是新的文章服务方法:

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

    现在$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;
      }
    );
    

    就是这样。这个简单的实现会跳过错误、错误的标题...处理。但这无论如何都有望实现...Check it here in action

    【讨论】:

    • 这不是任何类型的别名,而只是两个看起来非常相似的状态配置(并且确实重用了相同的模板)
    • @Geert 感谢您的评论。你的观点是正确和有效的。它帮助我扩展了答案并展示了另一种方式,即如何解决“别名”需求。会说,这可能更适合您... 注意:非常感谢您的评论和勇敢。只有这种方法(发表评论)才能帮助改进答案。太棒了!
    • 非常感谢!你的解决方案让我今天免于敲头和拉头发 :)
    猜你喜欢
    • 1970-01-01
    • 2016-07-31
    • 2014-10-28
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    • 2016-01-17
    • 1970-01-01
    • 2023-01-19
    相关资源
    最近更新 更多