Angular-渲染过滤数组问题

时间:2019-07-31 19:44:40

标签: arrays angular

我正在按照本教程进行操作,并且被卡在此功能中,在该功能中,单击锚点时必须显示一个经过过滤的数组(来自Firebase的对象)。我遵循了所有的实现步骤,但是缺少了一些东西……代码:

HTML:

<div class="row">
    <div class="col-3">
        <div class="list-group">
            <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.name}}
            </a>
        </div>
    </div>


<div class="col">
<div class="row">
    <ng-container *ngFor="let p of filteredProducts; let i =index">
        <div class="col">

            <div class="card" style="width: 15rem;">
                <img src="{{p.imageURL}}">
                <div class="card-body">
                    <h5 class="card-title">{{p.title}}</h5>
                    <p class="card-text">{{p.price | currency: 'EUR': true}}</p>
                    <a href="#" class="btn btn-primary">Add to cart</a>
                </div>
            </div>

        </div>
        <div></div>
    </ng-container>

       </div>
    </div>
</div>

TS课:

products:Product[]=[];
  filteredProducts: Product[]=[];
  category: string;
  categories$;
  constructor(
    private productService: ProductService, 
    private categoryService: CategoryService,
    private route: ActivatedRoute) { 
    this.categories$=this.categoryService.getCategories();
    this.productService.getAll().subscribe(products =>this.products=products)

    this.route.queryParamMap.subscribe(params =>{
      this.category = params.get('category');

      this.filteredProducts = (this.category) ?
      this.products.filter(p=>p.category===this.category) :
      this.products;
    });

  }

该服务正确地检索数据,但是当我记录过滤后的数组时,我什么也没得到……有人可以帮我吗?

编辑: enter image description here

1 个答案:

答案 0 :(得分:1)

您尝试在获取产品之前设置阵列。 subscription是一个异步操作,因此它不会按启动顺序执行,而是按结果到达的顺序执行,queryParams是一种可立即发出的可观察对象,因此在产品到达之前,subscribe正在执行,而是使用可观察的CombineLatest和地图运算符以及异步管道:

filteredProducts$: Observable<Product[]>;

....

const category$ = this.route.queryParamMap.pipe(map(params => params.get('category')));
this.filteredProducts$ = combineLatest(this.productService.getAll(), // combine the streams
                                       category$)
                           .pipe(
                             tap(([products, category])=> console.log(products, category)), // this is how you log in a stream
                             map(([products, category]) => // you'll have the latest value from both
                               (category) ? // run your filter
                                 products.filter(p => p.category.toLowerCase() === category.toLowerCase()) :
                                 products),
                             tap(filteredProducts => console.log(filteredProducts)) // this is how you log in a stream
                           );

然后在模板中就像使用类别$一样使用异步管道

<ng-container *ngFor="let p of filteredProducts$ | async; let i =index">

一个Observable只是一个定义如何处理数据流的定义。在该流之外记录事件不会向您显示该流中的值。 tap运算符的存在使您可以在流中记录内容