我们正在将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来完成,但是我不确定该怎么做。