简体   繁体   English

angular 项目中的 Observables (rxjs) 嵌套订阅

[英]Observables (rxjs) nested subscriptions in angular project

What is a better alternative to simplify my nested code below?有什么更好的选择来简化下面的嵌套代码? The code does work, but I do know that nested subscriptions aren't good what I've read.该代码确实有效,但我确实知道嵌套订阅并不是我所读到的。 I am also not sure if I should use mergeMap() or switchMap() in this particular example.我也不确定在这个特定示例中是否应该使用 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;
      }

You could remove the route paramMap subscriber, and instead use a resolver to replace this whole init process.您可以删除路由 paramMap 订阅者,而是使用解析器来替换整个初始化过程。

// someWork.resolver.ts // 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;
    }

}

In your router simply add:在您的路由器中只需添加:

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

And now in your actual ngOnInit:现在在您的实际 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;
}

Doing it this way, will also not load the component until the resolver... resolves.这样做,在解析器...解析之前也不会加载组件。 So can also avoid that line "this.isOpen = true" which i am guessing is a hack to wait for process' to finish.所以也可以避免那行“this.isOpen = true”,我猜这是等待进程完成的黑客行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM