我正在使用angularjs制作Web应用程序。我有一个从后端以以下结构获取的帖子列表:
[
{
post: {
postID: 1,
title: "sample title",
body: "so many paragraphs here",
post_date: "2018-12-26 02:21:35"
}
tags: [
{
tagTitle: "training"
},
{
tagTitle: "another tag"
}
]
}
]
我想根据我单击的标签过滤这些帖子。假设我点击了培训,我想显示在其标签的数组中具有 training 条目的帖子。
由于它是一个angularjs Web应用程序,因此ui-sref是posts(filter:'training'),而路径(url)将是posts?filter = training。
我用以下代码创建了一个过滤器:
function postsFilter() {
return function (collection, params) {
return collection.filter(function (item) {
var i, tagsArray = item.tags, len = tagsArray.length;
for (i = 0; i < len; ++i) {
return tagsArray[i].tagTitle === (
params.filter === "none" ? tagsArray[i].tagTitle :
params.filter;)
}
});
};
}
angular.module('app').filter('postsFilter', postsFilter);
在控制器中,我有以下代码;
function PostsController($filter) {
angular.extend(this, {
$onInit: () => {
this.filteredPosts = $filter('postsFilter')(this.posts, this.filter);
}
}
}
在组件中,我有以下代码:
const posts = {
bindings: {
posts: '<',
filter: '<'
},
templateUrl: 'path/to/my/posts.html',
controller: 'postsController'
};
angular.module('app').component('posts', posts).config(
[
'$stateProvider', function ($stateProvider) {
$stateProvider.state (
'posts', {
url: '/posts?filter',
component: 'posts',
params: {
filter: {
value: 'none'
}
},
resolve: {
posts: ['PostsService', function (PostsService) {
return PostsService.getPostList();
}],
filter: ['$transition$', function ($transition$) {
return $transition$.params();
}]
}
}
);
}
]);
然后在posts.html中,要显示过滤后的帖子,例如:
<div ng-repeat='post in $ctrl.filteredPosts'>
{{post.post.title}}
</div>
使用我当前的代码,当我单击链接以过滤帖子时(例如ui-sref ='posts({filter:'angularjs'})),帖子不会被过滤。网址更改,但帖子仍显示所有内容。默认情况下,帖子的网址显示 / posts?filter = none 。当我单击链接以过滤帖子时(假设标签为angularjs),URL更改为 / posts?filter = angularjs 。
我该如何纠正?
好的,现在将丢失的花括号放好后,它就可以工作了。我现在遇到的问题是,如果一个帖子有两个或多个标签,我将无法与其他标签一起过滤,而只能与第一个标签一起使用。
在此示例中,将仅使用 training 对其进行过滤,而不会使用另一个标签对其进行过滤。
答案 0 :(得分:1)
如果某个帖子包含两个或多个标签,则无法与其他标签一起过滤,它只能与第一个标签一起使用
您可以尝试像这样形成URl
posts?filter = angularjs&training
然后在过滤器功能中,形成一个过滤器标签数组。因此,您将有两个数组-集合和过滤器。现在,对Filters Array中的每个过滤器使用javascript Array Includes函数。如下所示(您需要根据模型结构进行调整):
let filteredCollection = new Array();
filters.foreach((filter) => {
if(collection.includes(filter)) {filteredCollection.push(collection)}
})
尽管这包括每次都解析两个数组,但这是目前最快的解决方案。
答案 1 :(得分:0)
我自己解决了这个问题。我将过滤器代码更改为以下代码(现在可以正常使用)。
function postsFilter () {
return function (collection, params) {
return collection.filter(function (item) {
var i, tagArray = item.tags, len = tagArray.length;
for (i = 0; i < len; ++i) {
if (params.filter === tagArray[i].tagTitle) {
return tagArray[i].tagTitle === (
params.filter === 'none' ? tagArray[i].tagTitle : params.filter
);
} else if (params.filter === 'none') {
return tagArray[i].tagTitle === (
params.filter === 'none' ? tagArray[i].tagTitle : params.filter
);
}
}
}
}
}
这使我想发生的事情成为现实,但我不喜欢自己做的那种骇客。我重复了代码。如果有人可以帮助使其变得 DRY ,那就太好了。