【问题标题】:Observable rxjs filter可观察的 rxjs 过滤器
【发布时间】:2020-03-30 22:16:17
【问题描述】:

在我的项目中,我想在每个产品页面中创建某种“推荐产品”, 但无法让我的函数过滤可观察。

我尝试过以不同的方式使用 .pipe(filter()),但没有用。

基本上该功能应该过滤具有相同typeid的产品,并将它们显示在适当的产品页面中,但在订阅我的所有产品后几乎卡住了(在下面标记)。

非常感谢!

import { Component, OnInit } from '@angular/core';
import { ProductService } from '../services/product.service';
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import  Product  from '../interfaces/product';
import { map, filter} from 'rxjs/operators';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-product',
  templateUrl: './product.component.html',
  styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
  recommandedProducts: Product[];
  allProducts:Product[];
  // allProducts:Observable< Product> = new Observable< Product>();
  product: Product;
  


  constructor(private productService: ProductService, private route: Router, private actRoute: ActivatedRoute) { }

  ngOnInit() {
    this.findRecommendedProducts(this.product)
  };

//From ProductService:
//   getProducts(){
//    return this.http.get(`${this.uri}`);
//    }
  findRecommendedProducts(currectProduct: Product){
    this.productService.getProducts().subscribe((data: Product[]) => {
      this.allProducts = data;
      console.log(this.allProducts)
      this.recommandedProducts = this.allProducts.filter(otherProduct => 
      otherProduct.type == currectProduct.type && otherProduct.id == currectProduct.id)
      console.log(this.recommandedProducts);
    });      
  };



}

【问题讨论】:

  • 向我们展示您从服务中获得的数据

标签: javascript angular observable


【解决方案1】:

rxjs 中的过滤器与Array.filter 不同。在 rxjs 中,过滤器用于发出通过所提供条件的值。所以如果你使用过滤器,根据条件,observable 要么发出你的数据,要么什么也不返回。

相反,您需要的是pipe(map) 以及Array.filter。此外,正如@jzzfs 指出的那样,您的错误显示currentProduct 可能是undefined,因此您可以在findRecommendedProducts 函数中传递一个默认值。

试试下面的代码。

findRecommendedProducts(currectProduct: Product = {} as Product) {
    this.productService.getProducts()
    .pipe(
        map((products: Product[]) => products.filter(product => product.type == currectProduct.type && product.id == currectProduct.id))
    )
    .subscribe((data: Product[]) => {
        this.recommandedProducts = data;
    });      
};

现在您订阅的数据应该直接返回recommendedProducts

【讨论】:

  • 感谢您的回答,但我收到 2 个新错误:1. 关于 currentProduct:Product = {}:类型“{}”缺少类型“产品”中的以下属性:product_Name、product_Description、 product_Price、product_Img 和另外 3 个。对于它的价值,我有一个导入到组件的 Product.ts 文件。 2.关于.filter:“对象”类型上不存在属性“过滤器”。
  • @moses 您的两个错误都是类型断言错误。 currentProduct 属于 Product 类型,因此它不能是空对象。您可以为Product 中的每个参数添加一个默认值,或者只需将findRecommendedProducts(currectProduct: Product = {}) 更改为findRecommendedProducts(currectProduct: Product = {} as Product)。第二个错误很奇怪。您的getProducts 是否返回Object 类型的值?它应该返回一个 Product[] 类型的值。我使用数组在 StackBlitz 上对此进行了测试,效果很好。
  • 这是类型问题。我并不是说您的数据不是数组。您是否在getProductsthis.http.get 中定义了任何返回类型?如果您也可以将getProducts 代码添加到问题中,这将有所帮助。
  • map(products =&gt; products.filter(product =&gt; product.type == currectProduct.type &amp;&amp; product.id == currectProduct.id)) 更改为map((products: Product[]) =&gt; products.filter(product =&gt; product.type == currectProduct.type &amp;&amp; product.id == currectProduct.id))。我已经编辑了答案以显示更改。
  • 好吧,您的过滤基于currentProduct 的值,最初它没有任何价值。因此过滤器将undefined 与每个typeid 进行比较并且没有得到任何数据。使用与您产品中的对象匹配的 typeid 初始化 currentProduct,您应该会看到该值。
【解决方案2】:

看起来传递给findRecommendedProductscurrectProductundefined,因为记录的this.allProducts 确实包含值。

话虽如此,请注意,当您定义product: Product 时,您只定义了它的类型,但还没有对其进行初始化。因此默认值是undefined——如果我没记错的话。

因此,例如将product: Product 更改为product: Product = {};,或者在构造函数或ngInit 中将值传递给它。

【讨论】:

  • 感谢您的回答,但很遗憾没有帮助。
  • 那么this.allProductscurrentProduct 的值是多少?如果数据太长,请更新您的问题。
  • this.allProducts 收到我所有的 18 个产品(上面标记为控制台),而 currentProduct 没有收到任何数据,因为正如我所说,该函数不会过滤 observable。
猜你喜欢
  • 2020-09-10
  • 2020-09-05
  • 2017-07-01
  • 2018-11-23
  • 1970-01-01
  • 1970-01-01
  • 2018-09-16
  • 2016-11-19
  • 2019-03-29
相关资源
最近更新 更多