Angular 过滤管不工作

Angular filter pipe doesn´t work

我正在使用 angular 5 和 angular material2,我正在尝试过滤 *ngFor 中的元素列表,就像您在此处看到的那样:

<div class="book" *ngFor="let book of documents |
 docCategory: fitleredCategories | sortBy: sortvalue : asc">

现在第二个过滤器在工作,但第一个不工作。

管道

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'docCategory'
})
export class DocCategoryPipe implements PipeTransform {

  transform(value: any, args?: any): any {
    let filtered = [];
    if (!value) {
      return;
    }

    filtered = value.filter((doc) => args.includes(doc.categories[0]));

    if (args.length === 0) {
      return value;
    } else {
      return filtered;
    }
  }

}

这是一组复选框,点击后将值推入 fitleredCategories 数组:

library.component.html

<li class="category" *ngFor="let category of categories">
  <mat-checkbox value="{{category.name}}" (click)="toggleCatInArray(category.name)">{{category.name}}</mat-checkbox>
</li>

toggleCatInArray 仅检查 fitleredCategories 上是否存在该值以推送或删除它。

但由于某种原因,管道无法正常工作。

library.component.ts

public fitleredCategories: any = [];

  public toggleCatInArray(category): void {
    this.toggleInArray(category, this.fitleredCategories);
  }

我没有在控制台或其他什么地方收到任何错误,它只是没有过滤 *ngFor

我认为你需要像这样组合管道

<div class="book" *ngFor="let book of (documents | docCategory: fitleredCategories) | sortBy: sortvalue : asc">

并且方法filter没有过滤当前数组。这是 return 一个新数组。试试这个代码:

... 
return value.filter((document) => ...)

问题是由2个原因造成的:

DocCategoryPipe 的错误实现:

@Pipe({
  name: 'docCategory'
})
export class DocCategoryPipe implements PipeTransform {

  transform(value: any[], categories: string[]): any[] {
    if (!value || !categories) {
      return [];
    }

    return value.filter((doc) => args.includes(doc.categories[0]));
  }
}

filteredCategories数组的变异:

为了重新 运行 模板中的管道,需要将新的 values/object 引用作为参数传递。 Angular 不会在您改变其参数之一时重新评估纯管道。

要解决此问题,请按如下方式重构您的代码:

 <li class="category" *ngFor="let category of categories">
  <mat-checkbox [value]="category.name" (change)="toggleCategory($event)">{{category.name}}</mat-checkbox>
</li>

import {MatCheckboxChange} from '@angular/material';

filteredCategories: string[] = [];
toggleCategory(event: MatCheckboxChange){
  const category = event.source.value;
  if(event.checked){
     this.filteredCategories= [...this.filteredCategories, category];
  }else{
     const matchIndex = this.filteredCategories.indexOf(category);
     this.filteredCategories= this.fitleredCategories.splice(matchIndex,1).
  }
}

由于您现在每次 add/remove 类别都使用新的对象引用设置 filteredCategories,因此 angular 将重新评估模板中的管道。