繁体   English   中英

如何过滤 Angular 中的类别 9

[英]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;});

在此处输入图像描述 在 CMD 中:

在此处输入图像描述

嗯,有一些错误,首先是你有

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM