首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Angular2中实现“类别过滤器”?

如何在Angular2中实现“类别过滤器”?
EN

Stack Overflow用户
提问于 2019-11-07 08:21:44
回答 1查看 2K关注 0票数 3

场景

在一个Angular2应用程序中,我在一个组件的视图中有一些代码,parent.component.html循环遍历一个items数组,并将每个item作为一个新组件输出:

代码语言:javascript
运行
复制
<div class="list-items">
  <!-- In the attached image, this is displayed as a coloured card -->
  <app-item *ngFor="let item of items" [item]="item"></app-list-slide>
</div>

每个item都有一个category键,它是一个id数组(对应于单独列表中每个类别的id)。

代码语言:javascript
运行
复制
// Item JSON
[
  { 
    "id": 1,
    "imageUrl": "https://via.placeholder.com/300x150/FF0000/FFFFFF?text=1",
    "title": "One",
    "categories": [ 1 ]
  }
]

// Category JSON
[
  { "id": 1, "title": "Red Cards" },
  { "id": 2, "title": "Blue Cards" }
]

要求

应用程序需要有一个过滤器,由类别动态生成(我可能会把它变成一个单独的组件):

代码语言:javascript
运行
复制
<div class="items-filter">
  <!-- In the attached image, this is displayed as a list of category buttons -->
  <div *ngFor="let category of categories">
    <a (click)="filterItemsByCategory(category)">{{ category.title }}</a>
  </div>
  <div class="btn-o">Reset</div>
</div>

单击类别项目时,应该只显示与该类别对应的项目。理想情况下,可以单击多个类别,但可以稍后再单击。

我能找到的所有过滤器的例子,似乎都使用基于文本输入的过滤,我真的不确定从哪里开始。

最终的产品应该是这样的:

类似的例子

下面是一个非常类似于我正在尝试做的事情的示例(但是文本输入框将被类别按钮的数组所取代):

文章:http://www.freakyjolly.com/angular-4-5-typescript-create-filter-list-with-check-boxes-to-select-from-list/

演示:https://freakyjolly.com/demo/AngularJS/Angular5FilterList/

问题

我的问题是,有没有人知道我正在尝试做的事情有什么好的工作例子,或者有人能建议一个好的开始?

我能想到的一种选择是在组件上创建与类别class="category-1 category-2"的ids相对应的类,但这似乎很混乱。

另一种选择是使用诸如共用或同位素之类的东西,但这些库中的许多Angular库似乎已经过时了:https://github.com/search?q=angular+masonry

谢谢

EN

Stack Overflow用户

回答已采纳

发布于 2019-11-07 10:07:38

这可以通过创建一个新的变量来实现,该变量是一个表示筛选项的数组,并对这些筛选项使用*ngFor。您可以结合使用Array.prototype.filterArray.prototype.includes来根据类别的id是否包含在id值组成的类别数组中来过滤项目:

组件:

代码语言:javascript
运行
复制
import { Component } from "@angular/core";
import { Item } from "./item.ts";
import { Category } from "./category.ts";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  items: Item[] = [
    {
      id: 1,
      imageUrl: "https://via.placeholder.com/300x150/FF0000/FFFFFF?text=1",
      title: "One",
      categories: [1]
    }
  ];
  categories: Category[] = [
    { id: 1, title: "Red Cards" },
    { id: 2, title: "Blue Cards" }
  ];
  // Create a shallow copy of the items array
  filteredItems: Item[] = [...this.items];

  filterItemsByCategory(category: Category) {
    this.filteredItems = this.items.filter((item: Item) => {
      return item.categories.includes(category.id);
    })
  }

  reset() {
    this.filteredItems = [...this.items];
  }
}

模板:

代码语言:javascript
运行
复制
<div class="items-filter">
    <!-- In the attached image, this is displayed as a list of category buttons -->
    <div *ngFor="let category of categories">
        <button type="button" (click)="filterItemsByCategory(category)">{{ category.title }}</button>
    </div>
    <button type="button" (click)="reset()" class="btn-o">Reset</button>
</div>

<div class="list-items">
    <!-- In the attached image, this is displayed as a coloured card -->
    <app-item *ngFor="let item of filteredItems" [item]="item">
    </app-item>
</div>

下面是一个用action编写的示例。如果您的日期是异步的,那么您可以使用*ngIf和/或默认设置为空数组[],以避免尝试对未定义/null执行数组操作。

此外,建议避免使用<a>元素作为按钮,而只使用<button>元素。另外,正如评论中提到的,angular team recommends NOT using pipes for filtering and/or sorting,所以我会避免做你链接的文章所建议的事情。

票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58740256

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档