有什么更好的方法可以避免在Angular Templates中使用方法调用



我试图避免在Angular Templates中使用方法调用,因为它们在那里是非性能的。假设我有一个名字列表:

const names: string[] = ['Billy', 'Mandy', 'Carl', 'Sheryl']

在我的模板中,我使用ngFor迭代列表并打印名称:

<ng-container *ngFor="let name of names">
<p>{{ name }}</p>
</ng-container>

但现在我只需要显示以"S"开头的名称,所以我改为:

<ng-container *ngFor="let name of names">
<p *ngIf="doesNameStartWithS(name)">{{ name }}</p>
</ng-container>

现在我在我的模板中有一个方法,我知道它会运行比必要的次数更多的次数。为了避免这种情况,我可以做一些类似的事情:

// this runs whenever the names list changes
const nameStartsWithSList: boolean[] = this.names.map((name: string): boolean => this.doesNameStartWithS(name));

然后将我的模板更改为:

<ng-container *ngFor="let name of names; let i = index;">
<p *ngIf="nameStartsWithSList[i]">{{ name }}</p>
</ng-container>

但这完全引入了一个新的列表,以避免模板中的方法调用。有更好的方法吗?

这是一个非常有趣的问题。

一种可能的解决方案是将前缀和字段传递给指令,并相应地对其进行操作。您可能可以使用renderer2作为一个更好的解决方案来呈现具有所需字段的段落,但这只是为了展示它的工作原理。

@Input() chars: string;
@Input() field: string;
constructor(private el: ElementRef) {}
ngOnInit() {
if (this.field.toLowerCase().includes(this.chars.toLowerCase())) {
(this.el.nativeElement as HTMLElement).innerHTML = `<p>${this.field}</p>`;
}
}

另一件事(实际上我刚刚意识到(是,您也可以将该指令用作组件。

<ng-container *ngFor="let name of names">
<showIfStartsWith chars="s" [field]="name"></showIfStartsWith>
</ng-container>

完整的演示在这里。

编辑:找到了另一个不那么奇怪的解决方案,而不使用指令作为组件。演示V2

编辑2:找到了另一个解决方案,使用该指令作为结构指令,展示了如何将多个参数传递给它。演示V3

我认为最好的方法是在ts文件中处理列表。

如果您的起始列表是:

const names: string[] = ['Billy', 'Mandy', 'Carl', 'Sheryl']

像一样设置

output(array, modifier) {
***modify array to return only starting with modifier letter***
return modifiedArray
}
modifier: string = 's'
const names: string[] = output(['Billy', 'Mandy', 'Carl', 'Sheryl'], modifier)

然后使用

<div *ngFor="let name of names"> ...

我认为在这种情况下,我会使用一个管道来转换或过滤给定的数据,类似于以下内容:

第一个上部管道

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'firstUpper',
})
export class FirstUpperPipe implements PipeTransform {
transform(value: string, letter: string): any {
if(value.startsWith(letter)){
return value;
}
}
}

毕竟在你的模板中,你可以这样使用:

<ng-container *ngFor="let name of names">
<p>{{ name | firstUpper:'S' }}</p>
</ng-container>

如果有或app.module.ts声明节,则应在pipes.module.ts中导入此管道。

最新更新