编辑:在Firefox ESR上不会发生。
如您所见,通过GIF,我在“材料”选项卡下(内部)对“材料表”有一个奇怪的渲染问题。
您可以看到实际上已为元素“分配了”空间,但行单元格并未立即呈现。
但是奇怪的是,如果我保持“开发人员工具栏”处于打开状态,那么它将正常工作!
您还将看到使用async
上的BehaviourSubject
管道输入了该行。如果我delay(1000)
进行next
通话,则会显示该行。
可扩展行(主要是div
,因为每次使用*ngIf
表达式都会被重建。
父组件:
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
...
})
export class DetailSmartComponent {
...
public readonly cronExpressions$ = new BehaviorSubject<List<CronExpressionModel>>([])
@Input('model')
public set modelInit(model: Model) {
this.model = model
const cronExprControl = model.getFormGroup().controls.cronExpressions
this.toModels(cronExprControl.value).subscribe(this.setCronExpressionModels)
if (this.lastSubscription) {
this.lastSubscription.unsubscribe()
}
this.lastSubscription =
cronExprControl.valueChanges.pipe(
filter(cronExprs => !!cronExprs),
switchMap(cronExprs => this.toModels(cronExprs))
).subscribe(cronExprs => this.setCronExpressionModels(cronExprs))
}
/** Last subscription, for when the input model changes. */
private lastSubscription: Subscription
private readonly toModels =
(cronExpressions: List<string>): Observable<List<CronExpressionModel>> =>
from(cronExpressions).pipe(
mergeMap(c => this.invokeCronService(c)),
toArray()
)
private readonly invokeCronService = (cron: string) =>
this.jobService.describeCron(cron).pipe(
catchError(() => of(Result.error('', 'Couldn\'t retrieve description'))),
map(result => result.get()),
map((description): CronExpressionModel => ({ cron, description }))
)
private readonly setCronExpressionModels =
(cronExpressions: List<CronExpressionModel>) =>
this.cronExpressions$.next(cronExpressions.slice().sort(asc))
...
}
模板:
<mat-tab-group">
<mat-tab label="Cron">
<ng-template matTabContent>
<cron-expressions
[isDisabled]="model.isDisabled"
[cronExpressions]="cronExpressions$ | async"
(removeCronExpression)="onRemoveCronExpression($event)"
></cron-expressions>
</ng-template>
</mat-tab>
...
子组件:
@Component({
selector: 'cron-expressions',
changeDetection: ChangeDetectionStrategy.OnPush,
...
})
export class CronExpressionsDumbComponent {
public readonly displayedColumns = [...]
@Input()
public isDisabled: boolean
@Input()
public cronExpressions: List<CronExpressionModel>
@Output()
public readonly removeCronExpression = new EventEmitter<string>(true)
}
export interface CronExpressionModel {
cron: string
description: string
}
模板:
<table mat-table [dataSource]="cronExpressions">
...
</table>