2015-10-07 107 views
4

我正在建设一个角度博客,目前正在研究路线。我有routeParams工作的路线,但有角度给它一个随机数和URL结束像http://localhost/kensproblems/#/posts/2如何使用标题而不是id做角度路由?

我希望它自动抓住标题和使用它作为参数的URL或使用属性称为ID json文件如http://localhost/kensproblems/#/posts/title-of-post

这可能与$routeParams

app.js

angular.module('app', [ 
    'ngRoute', 
    'app.controllers', 
    'ui.router', 
    'ngSanitize' 
]) 

.config(['$routeProvider', '$urlRouterProvider', function($routeProvider, $urlRouterProvider){ 
    $routeProvider 
    .when('/posts', { 
     templateUrl: 'views/posts.html', 
     controller: 'PostListController' 
    }) 
    .when('/posts/:id', { 
     templateUrl: 'views/singlepost.html', 
     controller: 'PostDetailController' 
    }) 
     .otherwise({ 
     redirectTo: '/' 
    }); 
}]); 

controllers.js

angular.module('app.controllers', ['app.directives']) 
    /* Controls the Blog */ 
    .controller('PostListController', ['$scope', '$http', function($scope, $http){ 
     $http.get('data/posts.json').success(function(response){ 
      $scope.posts = response; 
     }); 
    }]) 

    .controller('PostDetailController', ['$scope', '$http', '$routeParams', '$sce', function($scope, $http, $routeParams, $sce){ 
     $http.get('data/posts.json').success(function(response){ 
      $scope.post = response[$routeParams.id]; 
      console.log($routeParams.id); 
      console.log($scope.post.id); 
     }); 
    }]) 

posts.html

<div class="container" id="postList"> 
    <div class="row"> 
     <div class="col-md-10 col-md-offset-1"> 
      <div ng-repeat="post in posts | orderBy:post.date" class="post"> 
       <h2 class="blog-title"><a href="#/posts/{{posts.indexOf(post)}}">{{post.title}}</a></h2> 
       <span class="date">Posted on {{post.date | date:'MMM dd, yyyy'}}</span> 
       <div class="row top10"> 
        <div class="col-md-8"> 
         <div class="post-content">{{post.headline}}</div> 
         <a class="read-more" href="#/posts/{{posts.indexOf(post)}}">Read more</a> 
        </div> 
       </div> 
      </div> 
     </div> 
    </div> 
</div> 

singlepost.html

<div class="container" id="singlePost"> 
    <div class="row"> 
     <div class="col-md-10 col-md-offset-1"> 
      <h1>{{post.id}}</h1> 
      <h1>{{post.title}}</h1> 
      <span class="date">Posted on {{post.date | date:'MMM dd, yyyy'}}</span> 

      <h3>{{post.headline}}</h3> 
      <div class="postContent" ng-bind-html="post.content"></div> 
     </div> 
    </div> 
</div> 

回答

3

你需要改变两两件事,第一的URL是如何产生的,以及后的第二个如何恢复。

从标题

没有任何标题生成的URL将作为URL有效,所以你需要使用slugs

在视图:

<a class="read-more" href="#/posts/{{getSlug(post.title)}}">Read more</a> 

在控制器:

$scope.getSlug = function(text){ 
    return text.replace(/\W+/g, '-'); 
}; 

搜索后从塞

目前,你只是取出由阵列后作为索引,这在概念上是错误的(你会在删除一个帖子后注意到这一点)。相反,请在数组中进行搜索。如果您使用lodash,这将非常简单。

像这样的工作:

$scope.post = _.find(response, function(post) { 
    return post.title.replace(/\W+/g, '-') === $routeParams.id; 
}); 
+0

谢谢Lucio!我遵循完全按照你说的和它的工作:) 非常感谢你!我喜欢这个lodash图书馆 –

0

堆栈溢出不会让我回应还,所以我会张贴在这里。我看起来像你传递数组中的帖子的索引而不是其中一个属性。看看变化:

href="#/posts/{{posts.indexOf(post)}}" 

喜欢的东西:

ng-href="#/posts/{{post.title}}" 
+0

当我这样做,特定的帖子的原始内容不会传递到singlepost.html视图。身体,内容等不在那里。带有routeProvider的配置文件是否需要更改? –

+0

我不这么认为。在您的控制器中,您可以使用$ routeParams.id(这大概是在您传递帖子后。标题)使用标题,然后用http请求提取帖子的详细信息。我还建议移动你的http请求到服务而不是你的控制器。这里有一个很棒的Angular styleguide:https://github.com/johnpapa/angular-styleguide –