我创建了排序工具条,可以根据类别和价格过滤产品列表。按类别过滤可以正常工作。 我在根据产品价格进行过滤时遇到问题。如果我将类别设置为“ Smartfons”,并且对价格高于2000的产品进行过滤,则在我的情况下,它将正确返回Iphone X: 但是,当我将过滤条件更改为“全部”时,我有这部手机,它应该返回3部手机:
export class ProductComponent implements OnInit {
filteredProduct: Products[] = [];
products: Products[] = [];
currentSorting: string;
wrapper = true;
@ViewChild('filtersComponent')
filtersComponent: SortProductsComponent;
constructor(protected productsService: CategoriesProductsService) { }
sortFilters: any[] = [
{ name: 'Name (A to Z)', value: 'name' },
{ name: 'Price (low to high)', value: 'priceAsc' },
{ name: 'Price (high to low)', value: 'priceDes' }
];
priceFilters: any[] = [
{ name: 'All', value: 'all', checked: true },
{ name: 'Price > 2000', value: 'more_2000', checked: false },
{ name: 'Price < 500', value: 'less_500', checked: false }
];
ngOnInit() {
this.displayProducts();
}
displayProducts() {
this.productsService.getProducts().subscribe(product => {
this.products = product;
this.filteredProduct = product; });
}
onFilterChange(data) {
if (data.type === 'category') {
if (data.isChecked) {
// tslint:disable-next-line:prefer-for-of
for (let i = 0; i < data.filter.Products.length; i++) {
this.filteredProduct.push(data.filter.Products[i]);
}
} else {
this.filteredProduct =
this.products.filter(x => {
return x.CategoryId !== data.filter.Id; } );
}
} else if (data.type === 'price') {
this.filteredProduct = this.products;
if (data.isChecked) {
const priceFilter = data.filter.value;
if (priceFilter === 'all') {
this.filteredProduct = this.products;
} else if (priceFilter === 'more_2000' ) {
this.filteredProduct = this.products.filter(x => x.Price > 2000);
} else if (priceFilter === 'less_500' ) {
this.filteredProduct = this.products.filter(x => x.Price < 500);
}
}
}
}
SortProductComponent:
export class SortProductsComponent implements OnInit {
categoriesList: Categories[];
@Input()
priceFilters: any[];
// tslint:disable-next-line:no-output-on-prefix
@Output()
onFilterChange = new EventEmitter<any>();
showFilters = true;
sideShown = false;
constructor(private categoriesService: CategoriesProductsService) { }
ngOnInit() {
this.displayCategories();
}
displayCategories() {
this.categoriesService.getCategories().subscribe((data) => {
this.categoriesList = data;
});
}
onInputChange($event, filter, type) {
const change = $event.target.checked ? 1 : -1;
this.onFilterChange.emit({
type,
filter,
isChecked: $event.target.checked,
change
});
}
}
HTML模板:
<h5>Filter by categories</h5>
<form >
<div class="category-filter filter-wrapper" *ngFor = 'let filter of categoriesList'>
<div class="custom-control custom-checkbox">
<label class="fake-checkbox">
<input type="checkbox" class="custom-control-input" checked (change)='onInputChange($event, filter, "category")'>
<span class="custom-control-label"> {{filter.Name}}</span>
<span></span>
</label>
</div>
</div>
</form>
<h5>Filter by price</h5>
<form *ngIf = "showFilters">
<div class="custom-filter filter-wrapper" *ngFor = 'let filter of priceFilters'>
<label class="fake-checkbox">
<input type="radio" name="price" [checked]='filter.checked' (click)='onInputChange($event, filter, "price")'>
<span class="circle"><span class="fill"></span></span>
<span class="label">{{filter.name}}</span>
<span></span>
</label>
</div>
</form>
产品类别:
export class Products {
Id: number;
Name: string;
Description: string;
DetailedDescription: string;
Price: number;
IsNewProduct: boolean;
PromotionalProduct: boolean;
Image: string;
CategoryId: number;
}
我认为通过使用filter()方法,该方法将一个新数组返回给我,因此该数组上的过滤器只能运行一次。
我希望我的类别和价格过滤器可以像此页面一样工作:https://carlosroso.com/angular2-shop
欢迎任何帮助
答案 0 :(得分:1)
是的,除非您希望每次用户更改过滤器时都重新获取产品,否则您将需要保留原始产品列表(未过滤)并使用它来过滤您的列表。
这是我的代码:
ngOnInit(): void {
this.productService.getProducts().subscribe(
products => {
this.products = products;
this.filteredProducts = this.products;
},
error => this.errorMessage = <any>error
);
}
请注意,它将保留从服务返回的值,它们都在products
(这是完整列表)和filteredProducts
(这将始终是过滤后的列表)中。 (尽管它最初是所有产品的完整列表,但前提是该显示没有任何过滤器。)
然后,过滤器的源始终是原始列表:
performFilter(filterBy: string): IProduct[] {
filterBy = filterBy.toLocaleLowerCase();
return this.products.filter((product: IProduct) =>
product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
}
请注意,它使用this.products.filter
来确保始终从产品的完整列表中进行过滤。
您看起来会更像:
this.filteredProduct = this.products.filter(x => {
return x.CategoryId !== data.filter.Id; } );
}