【问题标题】:Observables (rxjs) nested subscriptions in angular project角度项目中的 Observables (rxjs) 嵌套订阅
【发布时间】:2021-05-10 06:16:15
【问题描述】:

有什么更好的替代方法来简化下面的嵌套代码?该代码确实有效,但我确实知道嵌套订阅并不是我所读到的。我也不确定在这个特定示例中是否应该使用 mergeMap() 或 switchMap()。

private subscriptions: Subscription = new Subscription();

ngOnInit() {
        this.subscriptions.add(this._route.paramMap.subscribe((paramMap: ParamMap) => {
          if (this.docType === 'invoice' && paramMap.has('invoiceId')) {
            this.mode = 'edit';
            this.subscriptions.add(this._invoiceService.getInvoice(this.invoiceId).subscribe(invoiceData => {
            //something here}));
          }
          else if (this.docType === 'quote' && paramMap.has('quoteId')) {
            this.mode = 'edit';
            this.subscriptions.add(this._quoteService.getQuote(this.quoteId).subscribe((invoiceData) => {//do something
            }));
          }
          else {
            //do something
            this.subscriptions.add(this._route.params.subscribe(params => {
              this.relatedProjectId = params['projectId']
            }));
           this.subscriptions.add(this._companyService.getCompany().subscribe(
              res => {
                this.showOwnCompany(res);
              }
            ))
          }
        }
        ));
        this.isOpen = true;
      }

【问题讨论】:

    标签: angular rxjs nested observable subscription


    【解决方案1】:

    您可以删除路由 paramMap 订阅者,而是使用解析器来替换整个初始化过程。

    // someWork.resolver.ts

    export class SomeWorkResolver implements Resolve<any> {
    
        constructor(
          private router: Router
          private invoiceService: InvoiceService,
          private quoteService: QuoteService
        ) {}
    
        resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any {
          if(route.param.has('invoiceId') {
              return this.invoiceService.getInvoice();
          } 
          if(route.param.has('quoteId') {
              return this.quoteService.getQuote();
          } 
          // implement the remainder
          return EMPTY;
        }
    
    }
    

    在您的路由器中添加:

    {
        path: 'somePath',
        component: SomeComponent,
        runGuardsAndResolvers: 'paramsOrQueryParamsChange',
        resolve: {
            information: SomeWorkResolver
        }
    }
    

    现在在您的实际 ngOnInit 中:

    ngOnInit() {
      // this has the information returned from the service call. 
      // can you use this information to determine what call was made?
      // IE Quote / Invoice / etc
      this.router.snapshot.data.information;
    }
    

    这样做,在解析器...解析之前也不会加载组件。所以也可以避免那行“this.isOpen = true”,我猜这是等待进程完成的黑客。

    【讨论】:

    • 谢谢。但是我需要在 ngOnInit 上订阅已解析的 observable 才能访问 res 数据,对吗?
    • 我根据您的建议实施了,它确实有效。不幸的是,我无法再保存文档了。可能是类似的问题,因为它也像获取数据一样嵌套
    • 这里还有关于 angular.io 上解析器的更多信息:angular.io/guide/…
    猜你喜欢
    • 2017-08-10
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-26
    • 2020-10-28
    相关资源
    最近更新 更多