在 Angular 中将 Word 转换为图标
Transform Word into Icon in Angular
我有一个页面,页脚包含很多健身房、联系方式、位置等信息...
我选择的健身房包含 5 种联系方式,即:
- 商业Phone
- Whatsapp
- Instagram
- 脸书
- 电子邮件
这是 json 的样子:
"ExibirContatos": [
{
"ID_TipoContato": "2",
"TipoDescricao": "Telefone comercial",
"Contato": "(31)2523-0672"
},
{
"ID_TipoContato": "9",
"TipoDescricao": "Whatsapp",
"Contato": "(31)98428-6287"
},
{
"ID_TipoContato": "5",
"TipoDescricao": "Instagram",
"Contato": "@br_fit_"
},
{
"ID_TipoContato": "7",
"TipoDescricao": "Facebook",
"Contato": "https://www.facebook.com/brfitbh/"
},
{
"ID_TipoContato": "4",
"TipoDescricao": "E-mail",
"Contato": "contato@brfitbh.com.br"
}
]
TS:
import {HttpClient} from '@angular/common/http';
import { Academia } from '../../classes/academia';
interface AcademiaRequest {
ACADEMIA_INFO: any;
}
export class HomePageComponent implements OnInit {
academia: Academia = new Academia();
constructor(private http: HttpClient) {}
ngOnInit() {
this.receberAcademia(this.academia);
}
receberAcademia(academia) {
this.http
.get<AcademiaRequest>(
'http://fitgroup.com.br/vysor_vendas_online/fg_vendas.php?AuthToken=FlnPoU230xGF&Metodo=academiaLoad&IDCliente=000949'
)
.subscribe(response => {
academia.nome = response.ACADEMIA_INFO.AcademiaDados.NomeAcademia;
academia.rua = response.ACADEMIA_INFO.AcademiaDados.EnderecoLogradouro;
academia.numero = response.ACADEMIA_INFO.AcademiaDados.EnderecoNumero;
academia.cep = response.ACADEMIA_INFO.AcademiaDados.EnderecoCEP;
academia.cidade = response.ACADEMIA_INFO.AcademiaDados.EnderecoCidade;
academia.estado = response.ACADEMIA_INFO.AcademiaDados.EnderecoUF;
academia.contatos = response.ACADEMIA_INFO.VendasOnline.ExibirContatos;
});
}
}
学术界Class:
export class Academia {
registros: number;
nome: string;
// Endereço
rua: string;
numero: string;
cep: string;
cidade: string;
estado: string;
// Contato
contatos: any[];
}
最后,我的 HTML:
<div class="col-lg-3 col-md-6 col-sm-6 mt-2 mb-4">
<h5 class="mb-4 ml-4 font-weight-bold">
CONTATO:
</h5>
<ul class="f-address">
<li *ngFor="let contatos of academia.contatos">
<p> {{contatos.TipoDescricao }}: {{ contatos.Contato }} </p>
</li>
</ul>
</div>
它正在打印类似的东西:
但是我不想要联系人的名字,我不想要"Telefone Comercial:","Whatsapp"等等...我希望这些名字被图标替换,fontawesome 图标,这些图标分别是:
<i class="fas fa-phone-alt"></i>
<i class="fas fa-whatsapp"></i>
<i class="fas fa-instagram"></i>
<i class="fas fa-facebook"></i>
<i class="fas fa-envelope"></i>
但是我不知道如何进行这样的转换,我什至在这段代码中想到过:
<div class="col-lg-3 col-md-6 col-sm-6 mt-2 mb-4">
<h5 class="mb-4 ml-4 font-weight-bold">
CONTATO:
</h5>
<ul class="f-address">
<li *ngFor="let contatos of academia.contatos">
<p> <i class="fas {{ contatos.TipoDescricao }}"></i> {{ contatos.Contato }} </p>
</li>
</ul>
</div>
但首先我需要转换为图标名称的其余部分 "fa-icon_name",我该怎么做?请帮助我!!
您可以使用管道来实现。创建一个将您的 contatos.TipoDescricao
作为输入并 returns 与之匹配的图标的管道。
@Pipe({
name: 'descriptionToIcon'
})
export class DescriptionToIconPipe implements PipeTransform {
private static readonly iconsForDescriptions:Array<{desc:string, icon:string}> = [
{desc: 'Telefone comercial', icon: 'fa-phone-alt'},
// Add all other texts and icons as pairs as well
]
transform(value: any, args?: any): any {
return DescriptionToIconPipe.iconsForDescriptions.find(item => item.desc === value).icon;
}
}
在你的 HTML
<div class="col-lg-3 col-md-6 col-sm-6 mt-2 mb-4">
<h5 class="mb-4 ml-4 font-weight-bold">
CONTATO:
</h5>
<ul class="f-address">
<li *ngFor="let contatos of academia.contatos">
<p> <i class="fas {{ contatos.TipoDescricao | descriptionToIcon}}"></i> {{ contatos.Contato }} </p>
</li>
</ul>
</div>
我可以看到两种解决方法:
1 - 创建一个方法来获取与描述相对应的图标,但它会影响性能,因为它会在每次更改时调用。
2 - 创建一个管道,这是推荐的方式:
import { Pipe, PipeTransform } from '@angular/core';
// Note that I have used Font Awesome 5.x for this demo.
const descriptionIconClassMapper = {
'E-mail': 'fas fa-envelope',
'Telefone comercial': 'fas fa-phone-alt',
Facebook: 'fab fa-facebook',
Instagram: 'fab fa-instagram',
Whatsapp: 'fab fa-whatsapp'
};
@Pipe({
name: 'descriptionToIconClass'
})
export class DescriptionToIconClassPipe implements PipeTransform {
transform<T extends keyof typeof descriptionIconClassMapper>(
description: T
): typeof descriptionIconClassMapper[T] {
return descriptionIconClassMapper[description];
}
}
并且在 HTML 中:
<div class="col-lg-3 col-md-6 col-sm-6 mt-2 mb-4">
<h5 class="mb-4 ml-4 font-weight-bold">
CONTATO:
</h5>
<ul class="f-address" *ngIf="academiaInfo$ | async as academiaInfo">
<li *ngFor="let contato of academiaInfo.VendasOnline.ExibirContatos">
<p><i class="mr-1" [ngClass]="contato.TipoDescricao | descriptionToIconClass"></i>{{ contato.Contato }}</p>
</li>
</ul>
</div>
一些小技巧:
1 - 不要直接从 components 调用 http 请求。创建一个 service 来包装它;
2 - 对于 GET
请求,更喜欢使用 async
pipe 而不是 subscribe
;
3 - 除了使用 any
,您还可以使用工具从 JSON 生成打字稿接口,例如 http://jsontots.com.
4 - 除非你有充分的理由使用 class
,否则最好使用 interfaces
,因为它不会影响构建大小。
5 - See the DEMO :)
我有一个页面,页脚包含很多健身房、联系方式、位置等信息...
我选择的健身房包含 5 种联系方式,即:
- 商业Phone
- 脸书
- 电子邮件
这是 json 的样子:
"ExibirContatos": [
{
"ID_TipoContato": "2",
"TipoDescricao": "Telefone comercial",
"Contato": "(31)2523-0672"
},
{
"ID_TipoContato": "9",
"TipoDescricao": "Whatsapp",
"Contato": "(31)98428-6287"
},
{
"ID_TipoContato": "5",
"TipoDescricao": "Instagram",
"Contato": "@br_fit_"
},
{
"ID_TipoContato": "7",
"TipoDescricao": "Facebook",
"Contato": "https://www.facebook.com/brfitbh/"
},
{
"ID_TipoContato": "4",
"TipoDescricao": "E-mail",
"Contato": "contato@brfitbh.com.br"
}
]
TS:
import {HttpClient} from '@angular/common/http';
import { Academia } from '../../classes/academia';
interface AcademiaRequest {
ACADEMIA_INFO: any;
}
export class HomePageComponent implements OnInit {
academia: Academia = new Academia();
constructor(private http: HttpClient) {}
ngOnInit() {
this.receberAcademia(this.academia);
}
receberAcademia(academia) {
this.http
.get<AcademiaRequest>(
'http://fitgroup.com.br/vysor_vendas_online/fg_vendas.php?AuthToken=FlnPoU230xGF&Metodo=academiaLoad&IDCliente=000949'
)
.subscribe(response => {
academia.nome = response.ACADEMIA_INFO.AcademiaDados.NomeAcademia;
academia.rua = response.ACADEMIA_INFO.AcademiaDados.EnderecoLogradouro;
academia.numero = response.ACADEMIA_INFO.AcademiaDados.EnderecoNumero;
academia.cep = response.ACADEMIA_INFO.AcademiaDados.EnderecoCEP;
academia.cidade = response.ACADEMIA_INFO.AcademiaDados.EnderecoCidade;
academia.estado = response.ACADEMIA_INFO.AcademiaDados.EnderecoUF;
academia.contatos = response.ACADEMIA_INFO.VendasOnline.ExibirContatos;
});
}
}
学术界Class:
export class Academia {
registros: number;
nome: string;
// Endereço
rua: string;
numero: string;
cep: string;
cidade: string;
estado: string;
// Contato
contatos: any[];
}
最后,我的 HTML:
<div class="col-lg-3 col-md-6 col-sm-6 mt-2 mb-4">
<h5 class="mb-4 ml-4 font-weight-bold">
CONTATO:
</h5>
<ul class="f-address">
<li *ngFor="let contatos of academia.contatos">
<p> {{contatos.TipoDescricao }}: {{ contatos.Contato }} </p>
</li>
</ul>
</div>
它正在打印类似的东西:
但是我不想要联系人的名字,我不想要"Telefone Comercial:","Whatsapp"等等...我希望这些名字被图标替换,fontawesome 图标,这些图标分别是:
<i class="fas fa-phone-alt"></i>
<i class="fas fa-whatsapp"></i>
<i class="fas fa-instagram"></i>
<i class="fas fa-facebook"></i>
<i class="fas fa-envelope"></i>
但是我不知道如何进行这样的转换,我什至在这段代码中想到过:
<div class="col-lg-3 col-md-6 col-sm-6 mt-2 mb-4">
<h5 class="mb-4 ml-4 font-weight-bold">
CONTATO:
</h5>
<ul class="f-address">
<li *ngFor="let contatos of academia.contatos">
<p> <i class="fas {{ contatos.TipoDescricao }}"></i> {{ contatos.Contato }} </p>
</li>
</ul>
</div>
但首先我需要转换为图标名称的其余部分 "fa-icon_name",我该怎么做?请帮助我!!
您可以使用管道来实现。创建一个将您的 contatos.TipoDescricao
作为输入并 returns 与之匹配的图标的管道。
@Pipe({
name: 'descriptionToIcon'
})
export class DescriptionToIconPipe implements PipeTransform {
private static readonly iconsForDescriptions:Array<{desc:string, icon:string}> = [
{desc: 'Telefone comercial', icon: 'fa-phone-alt'},
// Add all other texts and icons as pairs as well
]
transform(value: any, args?: any): any {
return DescriptionToIconPipe.iconsForDescriptions.find(item => item.desc === value).icon;
}
}
在你的 HTML
<div class="col-lg-3 col-md-6 col-sm-6 mt-2 mb-4">
<h5 class="mb-4 ml-4 font-weight-bold">
CONTATO:
</h5>
<ul class="f-address">
<li *ngFor="let contatos of academia.contatos">
<p> <i class="fas {{ contatos.TipoDescricao | descriptionToIcon}}"></i> {{ contatos.Contato }} </p>
</li>
</ul>
</div>
我可以看到两种解决方法:
1 - 创建一个方法来获取与描述相对应的图标,但它会影响性能,因为它会在每次更改时调用。
2 - 创建一个管道,这是推荐的方式:
import { Pipe, PipeTransform } from '@angular/core';
// Note that I have used Font Awesome 5.x for this demo.
const descriptionIconClassMapper = {
'E-mail': 'fas fa-envelope',
'Telefone comercial': 'fas fa-phone-alt',
Facebook: 'fab fa-facebook',
Instagram: 'fab fa-instagram',
Whatsapp: 'fab fa-whatsapp'
};
@Pipe({
name: 'descriptionToIconClass'
})
export class DescriptionToIconClassPipe implements PipeTransform {
transform<T extends keyof typeof descriptionIconClassMapper>(
description: T
): typeof descriptionIconClassMapper[T] {
return descriptionIconClassMapper[description];
}
}
并且在 HTML 中:
<div class="col-lg-3 col-md-6 col-sm-6 mt-2 mb-4">
<h5 class="mb-4 ml-4 font-weight-bold">
CONTATO:
</h5>
<ul class="f-address" *ngIf="academiaInfo$ | async as academiaInfo">
<li *ngFor="let contato of academiaInfo.VendasOnline.ExibirContatos">
<p><i class="mr-1" [ngClass]="contato.TipoDescricao | descriptionToIconClass"></i>{{ contato.Contato }}</p>
</li>
</ul>
</div>
一些小技巧:
1 - 不要直接从 components 调用 http 请求。创建一个 service 来包装它;
2 - 对于 GET
请求,更喜欢使用 async
pipe 而不是 subscribe
;
3 - 除了使用 any
,您还可以使用工具从 JSON 生成打字稿接口,例如 http://jsontots.com.
4 - 除非你有充分的理由使用 class
,否则最好使用 interfaces
,因为它不会影响构建大小。
5 - See the DEMO :)