如何在Angular2中实现“类别过滤器" [英] How can I implement a 'category filter' in Angular2

查看:92
本文介绍了如何在Angular2中实现“类别过滤器"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In an Angular2 app, I have some code in a component's view parent.component.html looping through an array of items and outputting each item as a new component:

<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).

Each item has a category key which is an array of ids (corresponding to the id of each category in a separate list).

// 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" }
]

要求

应用程序需要具有一个由类别动态生成的过滤器(我可能将其设为单独的组件):

Requirement

The app needs to have a filter, dynamically generated by the categories (I might make this into a separate component):

<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>

单击类别项目时,仅应显示与该类别相对应的项目.理想情况下,可以单击多个类别,但可以稍后使用.

When a category item is clicked, only the items corresponding to that category should be shown. Ideally, multiple categories could be clicked, but that can be for later.

我可以为过滤器找到的所有示例,似乎都使用基于文本输入的过滤,而且我不确定如何从此开始.

All the examples I can find for filters, seem to use text input based filtering, and I'm not really sure where to start with this.

最终产品应如下所示:

Final product should look like this:

这是一个与我尝试执行的操作非常相似的示例(但文本输入框将被类别按钮数组替换):

Here is an example of something very similar to what I am trying to do (but the text input box would be replaced with the array of category buttons):

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

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

我的问题是,是否有人知道我正在尝试做的任何好的工作示例,或者有人可以建议从这里开始的好地方吗?

My question is either, does anyone know of any good working examples of what I am trying to do, or can anyone suggest a good place to start with this?

我能想到的一个选择是在与类别class="category-1 category-2"的ID对应的组件上创建类,但这似乎很麻烦.

One option I can think of is to create classes on the component corresponding to the ids of the categories class="category-1 category-2" but this seems messy.

另一个选择是使用Masonary或Isotope之类的东西,但是许多Angular库似乎已经过时了: https://github.com/search?q=angular+masonry

Another option is using something like Masonary or Isotope, but a lot of the Angular libraries for these seem to be outdated: https://github.com/search?q=angular+masonry

谢谢

推荐答案

这可以通过创建一个新变量,一个表示已过滤项目的数组并将*ngFor与这些已过滤项目一起使用来实现.您将使用 Array.prototype.filter 以及 Array.prototype.includes 以根据类别的ID是否包含在ID值的类别类别数组中来过滤项目:

This can be achieved by create a new variable, an array representing the filtered items and using *ngFor with those filtered items. You'd use Array.prototype.filter along with Array.prototype.includes to filter items based on whether the id of the category is included in the item's categories array of id values:

组件:

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];
  }
}

模板:

<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>

以下是操作中的示例.如果您的日期是异步的(很可能是在您的实际应用程序中),则可以使用*ngIf和/或默认值为空数组[]以避免尝试对未定义/空值执行数组操作.

Here is an example in action. If your date is async, which it most likely is in your actual application, you can use *ngIf and/or defaults to empty arrays [] to avoid trying to perform array operations on undefined/null.

此外,建议避免使用<a>元素作为按钮,而仅使用<button>元素.另外,如评论中所述,角度小组建议不要将管道用于过滤和/或排序,所以我会避免做您链接的文章所建议的事情.

Also, it's recommend to avoid using <a> elements as buttons, and instead just use <button> elements. Also, as mentioned in a comment, the angular team recommends NOT using pipes for filtering and/or sorting, so I'd avoid doing what the articles you link suggest.

这篇关于如何在Angular2中实现“类别过滤器"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆