在Angular应用程序的模板中依靠多个Observable

时间:2018-09-08 10:18:40

标签: angular redux observable

我们正在将redux用于几乎所有应用程序。 通常,当我们使用从应用程序状态获取的数据时,将其保持为可观察状态,并在组件的模板中使用可观察状态。

例如:

*ngFor="let project of projects$ | async"

如果我们有一个包含两个(或更多)可观察对象的组件,正确的方法是什么?尤其是,当我们使用两个数据时: 迭代一个列表,然后在渲染时从另一个列表中获取一些细节?

我知道我可以为所有数据集订阅组件中的更改,将其存储在控制器中的单独变量中,并在模板中使用它。但是,我想知道是否有一种更优雅的方法,不需要解开可观察对象。

这是一个更具体的示例: 我有一个控制器:

export class PrincipleComponent implements OnInit {

  @select(['principleList', 'principles'])
  principles$: Observable<Principle[]>;

  @select(['domainPrincipleList', 'domainPrinciples'])
  domainPrinciples$: Observable<DomainPrinciple[]>;

  columnsToDisplay = ['id', 'title', 'description'];

  constructor(private principleActions: PrincipleActions,
              private domainPrincipleActions: DomainPrincipleActions,
              private domainActions: DomainActions) { }

  ngOnInit() {
    this.principleActions.loadPrinciples();
    this.domainPrincipleActions.loadDomainPrinciples();
    this.domainActions.loadDomains();
  }

}

在模板中,我尝试遍历原理,并在每次迭代中使用domainPrinciples中可用的信息:

<mat-card *ngFor="let principle of principles$ | async" class="principle-card">
      {{principle.name}}
      // Here I need to use some data coming from the domainPrinciples$ Observable
  </mat-card>

更新

显然,我不知道如何实现我所需要的: 因此,在我的控制器中,我有:

selectedDomainId: number = null;

  @select(['principleList', 'principles'])
  principles$: Observable<Principle[]>;

  @select(['domainList', 'domains'])
  domains$: Observable<Domain[]>;

  @select(['domainPrincipleList', 'domainPrinciples'])
  domainPrinciples$: Observable<DomainPrinciple[]>;

然后在我开始构建的模板中:

<div fxLayout="column"
     fxLayoutAlign="space-between stretch"
     fxLayoutGap="5px"
     class="fp-principles-list"
     *ngIf="{ domains: domains$ | async, principles: principles$ | async, domainPrinciples: domainPrinciples$ | async } as values;">

  <h1 class="mat-headline title">40 Principles Settings</h1>
  <h2 class="mat-subheader title">
    Principles for
    <small>
      <mat-form-field [floatLabel]="'never'" class="domain-selector">
        <mat-select placeholder="Generic definitions" [(ngModel)]="selectedDomainId" name="domain">
          <mat-option>
            Generic definitions
          </mat-option>
          <mat-option *ngFor="let domain of values.domains" [value]="domain.id">
            {{domain.title}}
          </mat-option>
        </mat-select>
      </mat-form-field>
    </small>
  </h2>

  <table mat-table [dataSource]="values.principles" class="mat-elevation-z4">

    <!-- Id Column -->
    <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef> No. </th>
      <td mat-cell *matCellDef="let element" class="td-id"> {{element.id}} </td>
    </ng-container>

    <!-- Name Column -->
    <ng-container matColumnDef="title">
      <th mat-header-cell *matHeaderCellDef> Title </th>
      <td mat-cell *matCellDef="let element" class="td-title"> {{element.title}} </td>
    </ng-container>

    <!-- Weight Column -->
    <ng-container matColumnDef="description">
      <th mat-header-cell *matHeaderCellDef>
        Description
      </th>
      <td colspan="2" mat-cell *matCellDef="let element" class="td-description" [innerHTML]="element.description"></td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
    <tr mat-row *matRowDef="let row; columns: columnsToDisplay"></tr>
  </table>
</div>

DomainPrinciple对象:

export class DomainPrinciple {
  id?: number;
  description?: string;
  domain?: IdRef;
  principle?: IdRef;
  createdBy: IdRef;
  dateCreated: Moment;
  updatedBy?: IdRef;
  lastUpdated?: Moment;
}

问题是,当用户更改所选域(在下拉列表中)时,我需要根据domainPrinciples列表中的所选域来解析description

我看到的唯一选择是创建一个函数,并传入principle,选定的域和整个域原理列表作为参数,并基于此解析描述。

但是,这感觉不对...我觉得应该通过redux来完成,但是我不确定该怎么做。

0 个答案:

没有答案