Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度:避免调用嵌套在另一个可观察对象中的可观察对象_Angular_Typescript_Rxjs_Ngrx - Fatal编程技术网

Angular 角度:避免调用嵌套在另一个可观察对象中的可观察对象

Angular 角度:避免调用嵌套在另一个可观察对象中的可观察对象,angular,typescript,rxjs,ngrx,Angular,Typescript,Rxjs,Ngrx,我有下面的代码,在组件加载时使用zip操作符找到购物车时进行一些API调用 ngOnInit() { const deliveryModes$ = this.checkoutService.getDeliveryModes(); const deliveryCountries$ = this.checkoutService.getDeliveryCountries(); const paymentMode$ = this.checkoutService.getPaym

我有下面的代码,在组件加载时使用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 
}

但我想知道是否有更好的代码块设计。

下面是一个工作示例的示例@


下面是工作样本的副本@


为什么不在第一次执行后取消订阅购物车的订阅?@ThirueswaranRajagopalan,因为我想在购物车更改时仍在该组件中更新购物车。只是出于好奇,是吗?据我所知,
ngOnInit
只被调用一次,对
checkoutService
的调用不在
ngrx/store select
方法的
subscribe
块内;因此,无论对
cart
@jrhee17进行了多少次更新,对后端服务的api调用都将在组件加载时执行一次。是的,我最初在应用商店订阅中进行了这些调用,所以我将它们取出,但我仍然存在这个问题。有趣。不过,deliveryModes$的类型是什么?它们也应该是可观察的,对吗?我知道,
Observable.zip
本身实际上并不执行请求,因此它们仍然执行api调用是没有意义的。你确定没有在其他任何地方调用
checkoutService
吗?为什么不在第一次执行后取消订阅购物车的订阅?@ThirueswaranRajagopalan,因为我想在购物车更改时仍在该组件中更新购物车。只是出于好奇,是吗?据我所知,
ngOnInit
只被调用一次,对
checkoutService
的调用不在
ngrx/store select
方法的
subscribe
块内;因此,无论对
cart
@jrhee17进行了多少次更新,对后端服务的api调用都将在组件加载时执行一次。是的,我最初在应用商店订阅中进行了这些调用,所以我将它们取出,但我仍然存在这个问题。有趣。不过,deliveryModes$的类型是什么?它们也应该是可观察的,对吗?我知道,
Observable.zip
本身实际上并不执行请求,因此它们仍然执行api调用是没有意义的。你确定没有在其他任何地方调用
checkoutService
吗?我知道mergeMap会将源代码与内部订阅(压缩服务)合并,这只是一个简单的问题。。但是为什么serviceList变量的输出中没有cart呢?我很乐意。因为我们没有指定结果选择器/转换器,所以它会发出内部的。检查一下,明白了!再次感谢!:)只是一个简单的问题,据我所知,mergeMap将把源代码与内部订阅(压缩服务)合并。。但是为什么serviceList变量的输出中没有cart呢?我很乐意。因为我们没有指定结果选择器/转换器,所以它会发出内部的。检查一下,明白了!再次感谢!:)
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 .... */
        });
}