这是一个很自以为是的答案。
这样的功能的使用是完全可以接受的。这将使模板更加清晰,并且不会造成任何重大开销。就像JB之前说过的那样,它将为单元测试奠定更好的基础。
我还认为,模板中包含的任何表达式都将被更改检测机制评估为一个函数,因此,无论模板中或组件逻辑中是否包含表达式,都没有关系。
只需将函数内部的逻辑保持在最低限度即可。但是,如果您对这种功能可能会对性能造成的影响保持警惕,我强烈建议您将ChangeDetectionStrategy
设为OnPush
,这被认为是最佳做法。有了这个,该函数将不会在每个周期都被调用,只有在Input
模板内部发生更改,某些事件等时才被调用。
(使用etc,因为我不知道其他原因了)。
就个人而言,我认为使用Observables模式更好,然后可以使用async
管道,并且仅当发出新值时,才对模板进行重新评估:
userIsAuthorized$ = combineLatest([
this.user$,
this.isAuthorized$
]).pipe(
map(([ user, authorized ]) => !!user && !!user.name && authorized),
shareReplay({ refCount: true, bufferSize: 1 })
);
然后,您可以像这样在模板中使用:
<ng-template *ngIf="userIsAuthorized$ | async">
...
</ng-template>
ngOnChanges
如果组件的所有因变量都是Inputs,并且还有很多逻辑要计算某个模板变量(这不是您所显示的情况),则可以使用另一种选择:
export class UserComponent implements ngOnChanges {
userIsAuthorized: boolean = false;
@Input()
user?: any;
@Input()
isAuthorized?: boolean;
ngOnChanges(changes: SimpleChanges): void {
if (changes.user || changes.isAuthorized) {
this.userIsAuthorized = this.userCheck();
}
}
userCheck(): boolean {
return this.user && this.user.name && this.isAuthorized || false;
}
}
您可以在模板中使用以下代码:
<ng-template *ngIf="userIsAuthorized">
...
</ng-template>