角度-将两个可观察对象合并为一个ngIf

时间:2019-02-26 09:38:12

标签: javascript angular typescript rxjs ngrx

我有一个步进器,该步进器受单个可观察到的条件

<ng-container *ngIf="!(categoriesLoading$ | async); else loading">
  <mat-vertical-stepper *ngIf="categories$ | async as categories">
    <mat-step>
      <categories-form [categories]="categories"></categories-form>
    </mat-step>
  </mat-vertical-stepper>
</ng-container>

现在我想添加另一个可观察的qualifications$

的条件

类似的东西:

<ng-container *ngIf="!(categoriesLoading$ | async); else loading">
  <mat-vertical-stepper *ngIf="categories$ | async as categories">
    <mat-step>
      <categories-form [categories]="categories"></categories-form>
    </mat-step>
    <mat-step>
      <qualifications-form [qualifications]="qualifications"></qualifications-form>
    </mat-step>
  </mat-vertical-stepper>
</ng-container>

在控制器中:

categories$: Observable<Array<Category>>;
categoriesLoading$: Observable<boolean>;
qualifications$: Observable<Array<Qualification>>;
qualificationsLoading$: Observable<boolean>;

如何正确执行此操作?

1 个答案:

答案 0 :(得分:2)

您可以查看可能会为您提供帮助的Rxjs zip组合运算符。

https://www.learnrxjs.io/operators/combination/zip.html

https://rxmarbles.com/#zip

在您的控制器中,您可以创建一个新的可观察对象,例如:

combined$: Observable<{ categories: Array<Category>, qualifications: Array<Qualification>}> = zip(
    this.categories$,
    this.qualifications$,
    (categories: Array<Category>, qualifications:Array<Qualification>) => { 
        return { categories, qualifications };
    }
);

将合并发射的值,然后可以使用它来获取合并的值:

<ng-container *ngIf="!(categoriesLoading$ | async); else loading">
  <mat-vertical-stepper *ngIf="combined$ | async as combined">
    <mat-step>
      <categories-form [categories]="combined.categories"></categories-form>
    </mat-step>
    <mat-step>
      <qualifications-form [qualifications]="combined.qualifications"></qualifications-form>
    </mat-step>
  </mat-vertical-stepper>
</ng-container>

您还可以使用zip来使加载的观测对象相互等待:

combinedLoading$: Observable<boolean> = zip(
    this.categoriesLoading$,
    this.qualificationsLoading$,
    (categoriesLoading: boolean, qualificationsLoading: boolean) => { 
        return categoriesLoading && qualificationsLoading;
    }
);