我有以下代码在组件加载时使用zip运算符找到购物车时会进行一些API调用。
ngOnInit() {
const deliveryModes$ = this.checkoutService.getDeliveryModes();
const deliveryCountries$ = this.checkoutService.getDeliveryCountries();
const paymentMode$ = this.checkoutService.getPaymentModeList();
this.store.select('cart').subscribe((cart: Cart) => {
if (cart) {
if (cart.entries.length > 0) {
this.cart = cart;
Observable.zip(deliveryModes$, deliveryCountries$, paymentMode$)
.subscribe(serviceList => {
this.deliveryModes = serviceList[0];
this.deliveryCountries = serviceList[1];
this.paymentModes = serviceList[2];
this.paymentMethod = this.paymentModes[0].code;
if (this.paymentMethod === 'paymetric') {
this.getPaymetricIframe();
}
this.initCheckoutForm();
});
} else {
this.router.navigate(['/']);
}
} else {
this.router.navigate(['/']);
}
});
}
我面临的问题是我在其他地方有一些更新购物车的代码,因此会再次调用此代码(因为它订阅了购物车),这意味着将再次进行三次调用,而我不要那样。组件初始化时,这三个服务只应调用一次。
我可以添加一些类似的东西,以避免调用Observable.zip并且它可以正常工作
if(this.cartInitialized) {
return
}
但我想知道这个代码块是否有更好的设计。
答案 0 :(得分:2)
下面是工作样本@ injected
的模仿ngOnInit() {
const deliveryModes$ = this.checkoutService.getDeliveryModes();
const deliveryCountries$ = this.checkoutService.getDeliveryCountries();
const paymentMode$ = this.checkoutService.getPaymentModeList();
/* subscribe while cart is valid ...
NOTE: replace takeWhile with filter, if navigation to root is not necessary ..*/
const cartChange$ = this.store.select('cart').takeWhile((cart :Cart) => cart && cart.entries.length);
/* keep updating local cart with changes....
navigate to root is cart is invalid, means subcription is completed ...*/
cartChange$.subscribe((cart :Cart) => this.cart = cart,
() => console.log('errr ..') ,
() => this.router.navigate(['/']));
/* first time a cart update comes, fetch serviceList(s) ... */
cartChange$.take(1)
.mergeMap(() => Observable.zip(deliveryModes$, deliveryCountries$, paymentMode$))
.subscribe(serviceList => {
/* things to do .... */
});
}