Angular 9:BehaviorSubject 不适用于远程数据

Angular 9: BehaviorSubject not working for remote data

我正在尝试使用 behaviorSubject 在任何组件之间传递数据。静态数据一切正常。但是当传递远程数据时(来自API)应该接收更新数据的组件正在接收更新前的数据。我尝试了几件事,但我不知道自己错过了什么。这是我的代码:

在我的服务中:appService

// BehaviorSubjects creation :
products = new BehaviorSubject<Array<IProduct>>([]);
currentProducts = this.products.asObservable();

category = new BehaviorSubject<string>('All Categories');
currentCategory = this.category.asObservable();

shopParams = new BehaviorSubject<ShopParams>(
    {brandId: [-1], CategoryId: 0, sort: 'name', pageNumber: 1, pageSize: 36, search: ''}
);
currentShopParams = this.shopParams.asObservable();

// Function to "update" the BehaviorSubject:
changeProducts(products: IProduct[]){
    this.products.next(products);
}
changeCategory(category: string){
    this.category.next(category);
}
changeShopParams(shopParams: ShopParams){
    this.shopParams.next(shopParams);
}
// Function to get data from API
getItems(shopParams: ShopParams) {
    let params = new HttpParams();
    shopParams.brandId.forEach(brandIdSlected =>{
        if (brandIdSlected !== -1) {
            params = params.append('brandId', brandIdSlected.toString());
        }
    });

    if (shopParams.CategoryId) {
        params = params.append('categoryId', shopParams.CategoryId.toString());
    }

    params = params.append('sort', shopParams.sort);
    params = params.append('pageIndex', shopParams.pageNumber.toString());
    params = params.append('pageSize', shopParams.pageSize.toString());

    return this.http.get<IPagination>(this.baseUrl + 'items', {observe: 'response', params})
    .pipe(
        map(response => {
          return response.body;
        })
      );
}

在我的第一个组件中:pageComponent

ngOnInit() {
    // Subscribe to category to get last update
    this.appService.currentCategory.subscribe(category => this.categoryNameSelected = category);
} 

// Method in which the category change
changeCategory(event){
    // some Code here  
    //Update category and shopParams for all suscribers
    this.appService.changeCategory(event);
    this.appService.changeShopParams(this.shopParams);  
    // Get the product from API base on category selected and new shopParams
    this.getItems();
   //Update products
    this.appService.changeProducts(this.products);
  }

// getItems function which call the getItem of my service to get data and subscribe
getItems() {
    this.appService.getItems(this.shopParams).subscribe(response => {
      this.products = response.data;
      this.shopParams.pageNumber = response.pageIndex;
      this.shopParams.pageSize = response.pageSize;
    }, error => {
      console.log(error);
    });   
  }

在我的第二个组件中:productCoponent

ngOnInit() {
    // Subscribe to category, shopParam and product to get last update
    this.appService.currentCategory.subscribe(category => this.categoryNameSelected = category);
    this.appService.currentShopParams.subscribe(shopParams => this.shopParams = shopParams);
    this.appService.currentProducts.subscribe(products => this.products = products);
}

pageComponent 假设在调用 onChangeCategory 时随时更新类别、shopParams 和产品,因此所有订阅者(如 productCompnent)都应获得更新的值。 我能够在 productCompnent 中获取 category 和 shopParams 的更新值,但是对于产品,我总是得到倒数第二个值而不是最后一个值我不知道我错过了什么。

此外,产品依赖于 shopParams,后者本身依赖于类别,而 pageComponent 只是更改类别。我不知道是否有简单的方法可以通过仅使用一个 behaviorSubject 来更新 productComponent 中的 shopParams 和产品?

将您的 changeCategory 和 getItems 方法更改为:-

changeCategory(event){
    // some Code here  
    //Update category and shopParams for all suscribers
    this.appService.changeCategory(event);
    this.appService.changeShopParams(this.shopParams);  
    // Get the product from API base on category selected and new shopParams
    this.getItems().subscribe(res => {
      this.appService.changeProducts(this.products);
    });
  }

// getItems function which call the getItem of my service to get data and subscribe
getItems() {
    return this.appService.getItems(this.shopParams).pipe(tap((response) => {
      this.products = response.data;
      this.shopParams.pageNumber = response.pageIndex;
      this.shopParams.pageSize = response.pageSize;
    }, error => {
      console.log(error);
    }));   
  }

说明 :- 您正在从 api 获取产品。您调用了 getitems,并且产品只会在调用订阅后收到最新值。但是您的代码不会等待 getitems 完成后再调用 product.next。这就是异步操作的工作方式。