[英]How to filter categories in Angular 9
我想在网上商店中按类别过滤。 实际上,我坚持使用 Mosh 的教程,因为我在浏览器或命令提示符中没有错误消息,但没有任何内容被过滤甚至显示。 我是 Angular 和/或 typescript 的绝对初学者,所以请善待^^我试图自己解决这个问题已经很久了,但它不起作用。 请帮帮我。
那是我的代码:
products.component.ts:
export class ProductsComponent {
products: Product[]= [];
filteredProducts: Product[] = [];
categories$: Observable<any>;
category: string;
products$: Observable<any>;
constructor(
route: ActivatedRoute,
productService: ProductService,
categoryService: CategoryService) {
this.filteredProducts;
productService.getAll().subscribe (products => this.products);
//Shows Categories in View
this.categories$ = categoryService.getAll();
route.queryParamMap.subscribe(params => {
this.category = params.get('category');
this.categories$.subscribe(res => console.log (res)); //Console.log 5 Categories Observable
//Setting the filtered Products Array
this.filteredProducts = (this.category) ?
this.products.filter(p => {
return p.category === this.category;
}) :
this.products;
console.log(this.filteredProducts); // Console.log FilteredProducts Array
});
}
}
products.component.html:
<div class="row">
<div class="col-3">
<div class="list-group">
<!-- Bei queryParams c.name auswählbare Kategorien / bei c.key nicht sowie bei c.$key nicht-->
<a *ngFor="let c of categories$ | async "
routerLink= "/"
[queryParams]="{ category: c.name }"
class="list-group-item list-group-item-action"
[class.active]="category === c.name">
{{ c.name }}
</a>
</div>
</div>
<div class="col-9">
<div class="row">
<ng-container *ngFor="let product of filteredProducts ; let i = index">
<div class="col">
<div class="card" style="width: 15rem;">
<img [src]="product.imageUrl" class="card-img-top" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{ product.title }}</h5>
<p class="card-text">{{ product.price | currency: 'EUR' }}</p>
<a href="#" class="btn btn-primary">Add to Cart</a>
</div>
</div>
</div>
<div *ngIf="(i + 1) % 2 === 0" class="w-100"></div>
</ng-container>
</div>
</div>
</div>
这里productService.getAll()
方法从 API 获取数据需要一些时间,但是route.queryParamMap
会立即执行,而这个 observable 订阅this.products
object 将是空的,这就是它无法过滤的原因。 您还没有在订阅中初始化this.products = products
。 要解决所有这些问题,您可以按如下方式实现:
export class ProductsComponent {
products: Product[]= [];
filteredProducts: Product[] = [];
categories$: Observable<any>;
category: string;
products$: Observable<any>;
constructor(
route: ActivatedRoute,
productService: ProductService,
categoryService: CategoryService) {
this.filteredProducts = [];
//Shows Categories in View
this.categories$ = categoryService.getAll();
route.queryParamMap.subscribe(params => {
this.category = params.get('category');
});
productService.getAll().subscribe (products => {
this.products = products;
//Setting the filtered Products Array
this.filteredProducts = (this.category) ?
this.products.filter(p => {
return p.category === this.category;
}) : this.products;
console.log(this.filteredProducts); // Console.log FilteredProducts Array
});
}
}
如果我 console.log 如下所示,这就是我得到的: productService.getAll().subscribe (products => { console.log(products); this.products = products;});
嗯,有一些错误,首先是你有
productService.getAll().subscribe (products => this.products);
一定是
productService.getAll().subscribe (products => this.products=products);
但这不起作用,因为是异步调用。
因此,首先更改您的 productService“缓存”产品。 你的服务喜欢
products:any[]
getAll()
{
return products?of(product):
this.httpClient.get("your-url").pipe(
tap(res=>this.products=res;
)
}
我们使用from 'rxjs' 并点击from 'rxjs/operators'
这使得 getProducts 返回一个 Observable 产品。 第一次调用,“产品”是未定义的,所以返回httpClient.get的响应。 procuts的tap make得到值,所以第二次被称为变量产品使用。
第二个错误是使用“构造函数”使用 ngOnInit 订阅 route.queryParamMap。
ngOnInit()
{
this.route.queryParamMap.subscribe(params => {
this.category = params.get('category');
//here you get all the products
this.productService.getAll().subscribe (
products => this.products=products);
//Setting the filtered Products Array
this.filteredProducts = (this.category) ?
this.products.filter(p => {
return p.category === this.category;
}) :
this.products;
console.log(this.filteredProducts); // Console.log FilteredProducts Array
});
}
好吧,另一种方法是使用 switchMap 并使过滤产品成为可观察的(然后我们使用过滤产品$ |异步)
this.filteredProduct$=this.route.queryParamMap.pipe(
switchMap(params=>{
this.category=params.get('category');
return this.productService.getAll().pipe(
switchMap(products=>{
const filteredProduct=!this.category?products:
products.filter(p => {
return p.category === this.category;
}) :
return of(filteredProduct):
})
)
})
)
注意:我不检查代码,但这是我的想法,我希望这可以有用
过滤部分存在问题,当您要根据类别过滤产品时,实际上并没有过滤。 原因是因为您的程序没有在p.category中获得产品类别。 因为您使用的是最新的 angular 以及最新的 firebase。 所以你应该使用p.payload.val().category 。 然后它将您的类别与this.category进行比较。
尝试给定的代码
productService.getAll().pipe(switchMap(products => {
this.products = products;
return route.queryParamMap;
}))
.subscribe(params => {
this.category = params.get('category');
this.filterProducts = (this.category) ?
this.products.filter(p => (p.payload.val().category)===this.category) :
this.products;
});
解决方案很简单>_< 我浪费了 2 个小时来解决。 当我们通过 c.key 给 queryParams - 它的值就像“面包” - 带有小写字母,但我们的 product.category 值是大写的,如“面包”,所以你必须给出类别名称的值 - 而不是类别键只需更改
这个:
<a *ngFor="let c of categories$ | async"
routerLink="/"
[queryParams]="{ category: c.key }"
class="list-group-item list-group-item-action"
[class.active] = 'category === c.key'
>
{{ c.payload.val().name }}
</a>
至:
<a *ngFor="let c of categories$ | async"
routerLink="/"
[queryParams]="{ category: c.payload.val().name }"
class="list-group-item list-group-item-action"
[class.active] = 'category === c.payload.val().name'
>
{{ c.payload.val().name }}
</a>
angular 最新版本的正确分析器是
products.component.ts:
import { switchMap } from 'rxjs/operators';
import { Product } from './../models/product';
import { Categorie } from './../models/categorie';
import { ActivatedRoute } from '@angular/router';
import { ProductService } from './../product.service';
import { Component, OnInit } from '@angular/core';
import { CategoryService } from '../category.service';
import { Observable } from 'rxjs';
@Component({
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.css']
})
export class ProductsComponent {
products: Product[]= [];
filteredProducts: Product[] = [];
categories$: Observable<any>;
category: string;
products$: Observable<any>;
constructor(
route:ActivatedRoute,
productService:ProductService,
categoryService:CategoryService) {
productService
.getAll().pipe(
switchMap(products=>{
this.products = products;
return route.queryParamMap;
}))
.subscribe(params =>{
this.category =params.get('category');
this.filteredProducts =(this.category)?
this.products.filter(p=>p.category === this.category):
this.products;
});`enter code here`
this.categories$ = categoryService.getAll();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.