简体   繁体   中英

How to refresh Font Awesome icon on Angular?

Is there any way to change font awesome icon dynamically? I want user to be able to select one of font awesome icons dynamically. It works only when you add class first time. The place where I try to do it is - MatDialog . There is form where user have to select icon, background color and category name. To select icon user should open another dialog.

在此处输入图像描述 在此处输入图像描述

I'm using Angular 9.1.4 and Font Awesome 5.13.0 .


That's what I tried:

1. Using ngClass

category-dialog.component.html

<div [ngStyle]="selectedColor">
    <i [ngClass]="selectedIcon"></i>
</div>

category-dialog.component.ts

openIconDialog(): void {
  const dialogRef = this.dialog.open(DialogIconSelectComponent, { width: '15rem' });
  dialogRef.afterClosed().subscribe(result => {
    this.selectedIcon = result;
  });
}

This works only first time. But when you try to change icon selectedIcon changes, but UI doesn't refresh element class.


2. Using @ViewChild

@ViewChild('iconElement') iconElement: ElementRef;

constructor(private dialog: MatDialog,
            private renderer: Renderer2) { }

openIconDialog(): void {
  const dialogRef = this.dialog.open(DialogIconSelectComponent, { width: '15rem' });
  dialogRef.afterClosed().subscribe((result: string) => {
    this.iconElement.nativeElement.className = result;
  });
}

This also works only first time.


3. Using @ViewChild and Renderer2

category-dialog.component.html

<div #colorElement [ngStyle]="selectedColor">
    <i #iconElement></i>
</div>

category-dialog.component.ts

@ViewChild('colorElement') parentElement: ElementRef;
@ViewChild('iconElement') childElement: ElementRef;

constructor(private dialog: MatDialog,
            private renderer: Renderer2) { }

openIconDialog(): void {
  const dialogRef = this.dialog.open(DialogIconSelectComponent, { width: '15rem' });
  dialogRef.afterClosed().subscribe(result => {
    this.replaceIcon(result);
  });
}

replaceIcon(iconClass: string): void {
  const i = this.renderer.createElement('i');
  this.renderer.setProperty(i, 'class', iconClass);
  this.renderer.removeChild(this.parentElement.nativeElement, this.childElement);
  this.renderer.appendChild(this.parentElement.nativeElement, i);
}

That doesn't work at all.


Is there any way how to change font awesome dynamically?

Resolution

Wasted lot of my free time to investigate how to resolve this issue. Tried everything with Renderer2 and all dirty Javascript methods. But one day I came up with idea to use innerHtml .

Rendering new string of inner HTML changes Font Awesome icons interactively.

category-dialog.component.html

<div [ngStyle]="selectedColor" [innerHtml]="selectedIconHtml"></div>

category-dialog.component.ts

openIconDialog(): void {
  const dialogRef = this.dialog.open(DialogIconSelectComponent, { width: '15rem' });
  dialogRef.afterClosed().subscribe((result: string) => {
    // EVERY TIME NEW ELEMENT WITH NEW FA CLASS
    this.selectedIconHtml = `<i class="${result}"></i>`;
  });
}

This solution - on every icon selection's changing <div> element content (inner html).

I solved this issue like this:

<div innerHTML="<i class='{{icon}}'></i>">
</div>

In this case, icon will be rerendered after value changes. innerHTML makes this happen easily. No need any code in TS file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM