我已经在app.component中注册了一些svg
public static MAT_ICONS_TO_REGISTOR: { name: string, url: string }[] = [
{name: 'broom', url: '../assets/imgs/broom.svg'},
{name: 'sources-icon', url: '../assets/imgs/camera_in.svg'}
];
AppComponent.MAT_ICONS_TO_REGISTOR.forEach(icon => {
this.matIconRegistry.addSvgIcon(icon.name,
this.domSanitizer.bypassSecurityTrustResourceUrl(icon.url));
});
但是当 *ngIf 存在时,它不会加载到组件 init 上,例如:
<div *ngIf="!isApproval">
<mat-icon svgIcon="broom"
(click)="onResubmitAction()">
</mat-icon>
</div>
在这种情况下,当条件成立时,将发送一个获取请求以从资产('http://localhost:4200/assets/imgs/broom.svg')获取图标,但它应该在组件初始化时加载它。
使用
*ngIf
时,只有内部条件为真时,元素才会被渲染。看起来 mat-icon
在渲染之前不会启动加载新图标的请求,因此为了加载图标,您需要渲染 mat-icon
。如果您希望元素不可见但仍呈现,您可以使用 hidden
属性:
<div [hidden]="isApproval">
<mat-icon svgIcon="broom"
(click)="onResubmitAction()">
</mat-icon>
</div>
当要隐藏的元素的 hidden
CSS 属性在某个时刻被覆盖时,
display
不起作用。所以添加下面的全局样式比较安全:
[hidden] {
display: none !important;
}
对于任何在 2024 年寻找答案的人,
你可以这样做,
const iconName = 'pencil';
const iconUrl = 'assets/icons/pencil.svg';
this.http.get(iconUrl, { responseType: 'text' })
.subscribe(svgContent => {
const trustedSvg = this.sanitizer.bypassSecurityTrustHtml(svgContent);
this.iconRegistry.addSvgIconLiteral(iconName, trustedSvg);
});
如果您使用 addSvgIcon 那么它将在渲染时加载 svg。因此,请使用接受 SVG HTML 而不是 URL 的 addSvgIconLiteral。 您对 SVG 资源进行 HTTP 调用,将其作为文本加载,然后将其传递给 addSvgIconLiteral。
如果您要加载多个图标,我建议像这样使用 forkJoin,
const requests: Observable<string>[] = iconDefinitions.map(icon => {
return this.http.get(icon.url, { responseType: 'text' });
});
forkJoin(requests).subscribe(svgs => {
svgs.forEach((svg, index) => {
const icon = iconDefinitions[index];
this.matIconRegistry.addSvgIconLiteral(icon.name, this.domSanitizer.bypassSecurityTrustHtml(svg));
});
});
希望有帮助。