【问题标题】:How to make Angular Routing with title instead of id?如何使用标题而不是 id 进行 Angular 路由?
【发布时间】:2016-01-05 09:37:49
【问题描述】:

我正在用 Angular 构建一个博客,目前正在研究路线。我有使用 routeParams 的路线,但 angular 给它一个随机数,并且 url 以 http://localhost/kensproblems/#/posts/2

结尾

我希望它要么自动获取标题并将其用作 URL 上的参数,要么使用 json 文件中名为 id 的属性,例如 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>

【问题讨论】:

    标签: javascript angularjs angular-routing


    【解决方案1】:

    您将需要更改两个主要内容,首先是如何生成 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, '-');
    };
    

    从 slug 搜索帖子

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

    这样的事情会起作用:

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

    【讨论】:

    • 谢谢卢西奥!我完全按照你说的做了,它奏效了:)非常感谢!我喜欢这个 lodash 库
    【解决方案2】:

    Stack Overflow 不允许我发表评论,所以我会在这里发布。我看起来像您在数组中传递帖子的索引而不是其中一个属性。看看变化:

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

    类似于:

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

    【讨论】:

    • 当我这样做时,该特定帖子的原始内容不会传递给 singlepost.html 视图。正文、内容等不存在。 routeProvider 的配置文件需要改吗?
    • 我不这么认为。在您的控制器中,您将使用 $routeParams.id(大概如果您传递 post.title)使用标题,然后通过 http 请求提取帖子的详细信息。我还建议将您的 http 请求移动到服务而不是控制器。这是一个优秀的 Angular 风格指南:github.com/johnpapa/angular-styleguide
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多