角度的,无法动态加载[svgIcon] =“ lItem.svgIcon”的自定义素材图标

时间:2019-12-28 17:42:42

标签: angular svg angular-material

使用角度8,我无法动态加载自定义svgIcon。

说明

进入我的component.html

      <div *ngFor="let lItem of node.nodeInformationsArray" class="itemDetails" [class]="lItem.cssClass">
          <button mat-icon-button *ngIf="lItem.hasOwnProperty('icon') || lItem.hasOwnProperty('svgIcon')" aria-hidden="false"
          class="material-icons-outlined" [matTooltip]="lItem.tooltip">
          <mat-icon *ngIf="lItem.icon">{{lItem.icon}}</mat-icon>
          <mat-icon *ngIf="lItem.svgIcon" [svgIcon]="lItem.icon"></mat-icon>
          <span *ngIf="lItem.txt" class="itemTxt">{{lItem.txt}}</span>
        </button>
      </div>

在此代码中,试图为angular material icons和自定义图标提供一个通用的解决方案,我尝试避免使用svgIcon解决方案和这一行,但是如果我在mat-icon的innerHtml ng材质图标的路径在控制台上出现错误。

<mat-icon *ngIf="lItem.svgIcon" svgIcon="inverter"></mat-icon>

因此,我尝试同时添加一个lItem.iconlItem.svgIcon ,它们可以静态工作(在我的情况下,在我的.ts构造函数中以“ inverter”作为已注册图标,它告诉我注册,URL等不是这里的问题。请注意

<mat-icon *ngIf="lItem.svgIcon" svgIcon="{{lItem.icon}}"></mat-icon>

也不起作用。

我的梦想和希望

      <div *ngFor="let lItem of node.nodeInformationsArray" class="itemDetails" [class]="lItem.cssClass">
          <button mat-icon-button *ngIf="lItem.hasOwnProperty('icon') || lItem.hasOwnProperty('svgIcon')" aria-hidden="false"
          class="material-icons-outlined" [matTooltip]="lItem.tooltip">
          <mat-icon *ngIf="lItem.icon">{{lItem.icon}}</mat-icon>
          <span *ngIf="lItem.txt" class="itemTxt">{{lItem.txt}}</span>
        </button>
      </div>

只需将我的自定义图标注册到我的构造函数中,即可同时使用自定义svgIcons和角度材质图标

3 个答案:

答案 0 :(得分:0)

您可以将自定义图标注册为素材图标。

import { NgModule } from "@angular/core";
import { MatIconModule, MatIconRegistry } from "@angular/material/icon";
import { DomSanitizer } from "@angular/platform-browser";

@NgModule({
  exports: [MatIconModule]
})
export class DemoMaterialModule {
  customIcons: Array<[string, string]> = [["hat", "assets/hat.svg"]];
  constructor(iconRegistry: MatIconRegistry, sanitizer: DomSanitizer) {
    this.customIcons.forEach(([iconName, iconPath]) => {
      iconRegistry.addSvgIcon(
        iconName,
        sanitizer.bypassSecurityTrustResourceUrl(iconPath)
      );
    });
  }
}

模板:

<mat-icon svgIcon="hat"></mat-icon>

要与动态变量一起使用:

<!-- hatName = 'hat' -->
<mat-icon [svgIcon]="hatName"></mat-icon>

Demo在Stackblitz上

重要提示

hatName必须是与自定义svgIcon 名称而不是路径对应的字符串!

答案 1 :(得分:0)

您可以这样做。我假设您有一个属性名称图标,然后从下面的代码从服务器后端获取它:

private getIconFromData(dataResult: any[]) {
    dataResult.forEach((folder) => {
        folder.iconAsync$ = CacheService // get resource from cache
              .get(
                  folder.icon, // 'user-profile-icon'

                  // if not found from cache then calling http request.
                  // when get a response, we're gonna cache it to reuse
                  this.httpClient.get(`${baseUrl}/${folder.icon}.svg`, { responseType: 'text' }),
              )
              .pipe(
                  switchMap((resource: string) => {
                      this.matIconRegistry.addSvgIconLiteral(
                          folder.icon,
                          this.domSanitizer.bypassSecurityTrustHtml(resource)
                      );

                      return of(folder.icon);
                  }),
                  take(1)
              );
    });
}

您迭代数据结果中的每个项目,并将mat-icon的输入[svgIcon]设置为Observable<string>

<ng-container *ngFor="let folder of dataResult">
    <mat-icon *ngIf="folder && (folder.iconAsync$ | async) as icon" [svgIcon]="icon" inline="true"></mat-icon>
</ng-container>

让您清楚地想象一个模型类

export class FolderModel {
    icon: string;
    iconAsync$?: Observable<string> // this is optional property. Just use it on template html
}

答案 2 :(得分:-1)

拼写错误lItem.icon

<mat-icon *ngIf="lItem.svgIcon" [svgIcon]="lItem.icon"></mat-icon>

代替lItem.svgIcon

<mat-icon *ngIf="lItem.svgIcon" [svgIcon]="lItem.svgIcon"></mat-icon>

但是仍然必须同时具有两个版本,并且无法将它们合并为用于角度和自定义图标的版本,因为例如,如果svgIcon设置为search,则会产生错误:

<mat-icon *ngIf="lItem.svgIcon" svgIcon="{{lItem.svgIcon}}"></mat-icon>

因此,唯一的解决方法是:

        <mat-icon *ngIf="lItem.icon">{{lItem.icon}}</mat-icon>
        <mat-icon *ngIf="lItem.svgIcon" svgIcon="{{lItem.svgIcon}}"></mat-icon>

使用svgIcon属性和icon将自定义图标设置为成角度