我在 Angular 中创建了一个过滤器和排序管道,并将其链接如下。但管道链接不起作用。如果我只使用单个管道,它可以工作,但如果我使用如下所示的两个管道,则只有过滤器功能有效,排序管道不起作用。有人可以告诉我我犯了什么错误吗?
<div class="grid-container">
<div class="grid-item" *ngFor="let prod of (productsList.products | sort:sortProductSelected | filterOnPrice:priceRange )">
<div class="card" style="width: 18rem;border: 0px;">
<img src="{{prod.thumbnail}}" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">{{prod.brand}}</h5>
<p class="card-text">${{prod.price}}</p>
<p class="card-text">{{prod.description}}</p>
<a target="_blank" class="btn btn-primary" (click)="viewProduct(prod.id)">View Product</a>
</div>
</div>
</div>
</div>
</div>
对管道进行排序
export class SortPipe implements PipeTransform {
transform(value: any[], ...args: any): any[] {
if(args){
switch(args[0]){
case 'Price low to hight':
value.sort((a,b)=>{
if(a.price<b.price) return -1;
else if(a.price>b.price) return 1;
return 0;
console.log("value");
})
break;
case 'Price High to Low' :
value.sort((a,b)=>{
if(a.price>b.price) return -1;
else if(a.price<b.price) return 1;
return 0;
})
break;
case 'Ratings':
value.sort((a,b)=>{
if(a.rating<b.rating) return -1;
else if(a.rating>b.rating) return 1;
return 0;
})
break;
case 'Discounts' :
value.sort((a,b)=>{
if(a.discountPercentage<b.discountPercentage) return -1;
else if(a.discountPercentage>b.discountPercentage) return 1;
return 0;
})
break;
default: return value;
}
}
return value;
}
}
过滤管
export class FilterOnPricePipe implements PipeTransform {
transform(value: any[], ...args: any): any[] {
let FliteredArray:any[] =[];
FliteredArray = value.filter((a)=>{
console.log(a.price);
console.log(FliteredArray);
return a.price<=args[0];
})
console.log(FliteredArray);
return FliteredArray;
}
}
最好先使用
filterPipe
,然后执行sortPipe
,当我这样做时效果很好,因为我们删除了不必要的值并对其进行排序将提高性能!
我猜输入参考没有改变,所以你遇到了这个问题!
因为当我更改
sortPipe
中的第45行时,它开始正常工作(无需交换管道),所以我猜需要更新数组的引用才能触发管道。
return [...value];
我认为你应该先执行过滤然后排序,因为它有意义并且不需要更新参考!
下面是一个工作示例!
ts
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { FilterOnPricePipe } from './filter.pipe';
import { SortPipe } from './sort.pipe';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, FilterOnPricePipe, SortPipe, FormsModule],
template: `
sortProductSelected
<select [(ngModel)]="sortProductSelected">
<option *ngFor="let state of states" [ngValue]="state.name">
{{ state.name }}
</option>
</select><br/>
<input type="number" [(ngModel)]="priceRange"/>
<div class="grid-container">
<div class="grid-item" *ngFor="let prod of (productsList.products | filterOnPrice:priceRange | sort:sortProductSelected )">
<div class="card" style="width: 18rem;border: 0px;">
<img src="{{prod.thumbnail}}" class="card-img-top" alt="..."/>
<div class="card-body">
<h5 class="card-title">{{prod.brand}}</h5>
<p class="card-text">$ {{prod.price}}</p>
<p class="card-text">{{prod.description}}</p>
<a target="_blank" class="btn btn-primary" (click)="viewProduct(prod.id)">View Product</a>
</div>
</div>
</div>
</div>
`,
})
export class App {
states = [
{ name: 'Price low to hight' },
{ name: 'Price High to Low' },
{ name: 'Ratings' },
{ name: 'Discounts' },
];
sortProductSelected = 'Price low to hight';
priceRange = 15;
name = 'Angular';
productsList = {
products: [
{
thumbnail: 'https://placehold.co/600x400',
brand: 'test',
price: 1,
rating: 1,
discountPercentage: 1,
description: 'test',
id: 1,
},
{
thumbnail: 'https://placehold.co/600x400',
brand: 'test',
price: 2,
rating: 2,
discountPercentage: 2,
description: 'test',
id: 2,
},
{
thumbnail: 'https://placehold.co/600x400',
brand: 'test',
price: 3,
rating: 3,
discountPercentage: 3,
description: 'test',
id: 3,
},
],
};
viewProduct(e: any) {}
}
bootstrapApplication(App);