使用 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);
}
我在 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);
}