使用 Rxjs 在 Angular 中进行状态管理

State management in Angular using Rxjs

我在 Angular 应用程序中使用 Behavior Subject 管理我的状态。我正在使用两项服务。一种使用网络套接字执行发送和获取请求,另一种将数据存储在可观察对象中。一旦检索到数据,我就将数据传递给行为主体。我在这里遇到问题。一切正常,除了当我删除该项目并按下后退按钮时。在此过程中,我的一些数据丢失了。我不知道为什么会这样。这是我的代码:

cart.store.ts // for managing state

private cartItems$ = new BehaviorSubject<Product[]>(null);
private items: Product[] = [];

setCart(cartItems: Product[]) {
    this.cartItems$.next(cartItems);
}

setSingleItem(item: Product) {
    this.items.push(item);
    this.cartItems$.next(this.items);
}

deleteCart(item: Product) {
    this.cartItems$.subscribe((res) => {
      let index;
      for (let i = 0; i < res.length; i++) {
         if (item.upc === res[i].upc) {
            index = i;
        }
      }
     res.splice(index, 1);
   });
}

cart.component.ts //calls cart service and fetches the data

getCartItems() {
if (!this.cartItems?.length) {
  const payload = this.localStorageService.getData(LOCAL_STORAGE_KEY.PHONE);
  this.cartService.getCart(payload).then((res) => {
    //after fetching storing the data
    this.cartStore.setCart(res);
    for (let x = 0; x < res.length; x++) {
      this.totalPrice = this.totalPrice + res[x].price;
    }
    this.cartItems$ = this.cartStore.getCart();  //using async pipe to display in template
  });
}
}

cart.service.ts //for getting and removing data

getCart(payload): Promise<any> {
this.socketService.sendMessage(AUTH_EVENTS.ON_DEVICE_CONNECT, payload);
const serverRes = (async () => {
  try {
    const data = await this.socketService.receivedJustSingleValue(
      CART_EVENTS.GET_CART_ITEMS,
    );
    if (data) {
      return data;
    } else {
      throw new Error('some shit happened');
    }
  } catch (error) {
    return error;
  }
})();
return serverRes;
}   

//remove cart works the same way

当我删除一个项目并按下后退按钮时,我的数据丢失了。谁能告诉我怎么了?

问题出在 deleteCart 函数中。您订阅了可观察的但永远不会取消订阅。所以每次调用 next() 时,deleteCart 都会再次运行并删除一个项目。

您可以使用BehaviorSubject.value获取当前项目。结果应该是这样的:

private cartItems$ = new BehaviorSubject<Product[]>(null);
// private items: Product[] = [];

setCart(cartItems: Product[]) {
    this.cartItems$.next(cartItems);
}

setSingleItem(item: Product) {
    this.cartItems$.next([...this.cartItems$.value, item]);
}

deleteCart(item: Product) {
    const items = this.cartItems$.value;
    let index;
    for (let i = 0; i < items.length; i++) {
        if (item.upc === items[i].upc) {
            index = i;
        }
    }
    items.splice(index, 1);
    this.cartItems$.next(items);
}