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 将重新评估模板中的管道。
我正在使用 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 将重新评估模板中的管道。