如何使 Angular 路由带有标题而不是 id?
How to make Angular Routing with title instead of id?
我正在与 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>
Stack Overflow 还不允许我发表评论,所以我会 post 在这里。我看起来像您在数组中传递 post 的索引而不是其中一个属性。看变化:
href="#/posts/{{posts.indexOf(post)}}"
类似于:
ng-href="#/posts/{{post.title}}"
您需要更改两个主要内容,首先是如何生成 URL,其次是如何恢复 post。
从标题生成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
中搜索 post
目前,您只是从数组中获取 post 作为索引,这在概念上是错误的(删除一个 post 后您会注意到这一点)。相反,通过数组进行搜索。如果您使用 lodash.
,这将非常简单
像这样的东西会起作用:
$scope.post = _.find(response, function(post) {
return post.title.replace(/\W+/g, '-') === $routeParams.id;
});
我正在与 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>
Stack Overflow 还不允许我发表评论,所以我会 post 在这里。我看起来像您在数组中传递 post 的索引而不是其中一个属性。看变化:
href="#/posts/{{posts.indexOf(post)}}"
类似于:
ng-href="#/posts/{{post.title}}"
您需要更改两个主要内容,首先是如何生成 URL,其次是如何恢复 post。
从标题生成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
中搜索 post目前,您只是从数组中获取 post 作为索引,这在概念上是错误的(删除一个 post 后您会注意到这一点)。相反,通过数组进行搜索。如果您使用 lodash.
,这将非常简单像这样的东西会起作用:
$scope.post = _.find(response, function(post) {
return post.title.replace(/\W+/g, '-') === $routeParams.id;
});