我们的团队正在开发一个非常复杂的表单引擎,它有许多重要的节点,例如
form
,container
,field
等。不用说,这些节点的类计算非常复杂 - 可能有10多个条件条件非常复杂的类。由于 Angular 为我们提供了多种方法来在 .ts
而不是 .html
中实现组件逻辑,因此我们使用函数方式来实现,如下所示:
[ngClass]="calculateSomeDamnComplexConditionsAndReturnAHugeNGClassObject()"
但是当我用谷歌搜索该主题时,我看到很多“模板中的函数调用是不好的做法”诸如here或here之类的评论。好吧,模板中的函数调用是不好的做法,可能会导致性能问题,但在 2023 年,在模板中实现所有复杂的类名计算将是相当疯狂的。模板不适合进行像这样的复杂计算:
<p [ngClass]="{
'text-success':celeb.country === 'USA',
'text-secondary':celeb.country === 'Canada',
'text-danger':celeb.country === 'Puorto Rico',
'text-info':celeb.country === 'India'
}">{{ celeb.artist }} ({{ celeb.country }})
这个例子只有4个条件类,但是如果条件类很多,而且有很多节点需要复杂的条件类计算怎么办
所以问题是:有角度的家伙,如何在 2023 年在组件类中实现复杂的类名计算而不出现性能问题?
我认为计算 css 类字符串对性能来说并不是那么糟糕。但是,当变量只是组件
calculateSomeDamnComplexConditionsAndReturnAHugeNGClassObject
时,您可以使用变量,并分配返回组件中的值的方法 ngOnInit()
。
当您使用循环 ngFor
时,您可以创建额外的字段,例如 celebs.forEach(item => item.style = this.getStyle(item.country))}
并在模板中使用 [ngClass]=celeb.style
。
或者,您可以将计算移至自定义纯管道,该管道返回包含所有必要类的字符串。
这样,您甚至可以在管道的方法中拆分计算。
@Pipe({name: 'complexClassPipe'})
export class ComplexClassPipe implements PipeTransform {
transform(value: ArrayItem) {
return this.getClassList(value);
}
private getClassList(item: ArrayItem) {
return [this.getClassForCountry(item.country)/*, call other methods*/].join(' ');
}
private getClassForCountry(country: string) {
switch (country) {
case 'USA':
return 'text-success';
case 'Canada':
return 'text-secondary';
case 'Puorto Rico':
return 'text-danger';
case 'India':
return 'text-info';
}
}
}
然后像这样使用它:
<p [ngClass]="celeb | complexClassPipe">{{ celeb.artist }} ({{ celeb.country }})