2

我通过 iconName 调查了 fontawesome 图标的动态加载问题。但是代码不起作用。是什么原因?最佳做法是什么?为什么我需要在指令 ngOnInit() 挂钩中调用 ngOnChanges()?我在浏览器中遇到的错误是“FontAwesome:找不到图标。看起来您为此组件提供了一个空或未定义的图标对象。”

import { AppComponent } from './app.component';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { library, dom } from '@fortawesome/fontawesome-svg-core';
import { fas,faCheck, faCalendar, faTimes } from '@fortawesome/free-solid-svg-icons';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { IconDirective } from './icon.directive';

@NgModule({
  declarations: [AppComponent, IconDirective],
  imports: [BrowserModule, FontAwesomeModule],
  providers: [],
  bootstrap: [AppComponent],
  entryComponents: [FaIconComponent],
})
export class AppModule {
  constructor() {
    library.add(fas,faCheck, faCalendar, faTimes);
    dom.watch();
  }
}
import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    template: '<div iconDirective></div>'
})
export class AppComponent {
    constructor() { }
}
import { Directive, OnInit, ViewContainerRef, ComponentFactoryResolver }
from '@angular/core';
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
import { faCheck, faCalendar, faTimes } from '@fortawesome/free-solid-svg-icons';
import { icon } from '@fortawesome/fontawesome-svg-core';

@Directive({
  selector: '[iconDirective]'
})
export class IconDirective{
   constructor(      
      public viewContainerRef: ViewContainerRef,
      private componentFactoryResolver: ComponentFactoryResolver) {
    }
    ngOnInit() {
      const componentFactory =
          this.componentFactoryResolver.resolveComponentFactory(FaIconComponent);
      const componentRef =
          this.viewContainerRef.createComponent(componentFactory);
      (<FaIconComponent>componentRef.instance).icon =
           icon({iconName: 'times', prefix: 'fas'});
      // (<FaIconComponent>componentRef.instance).iconProp = faCheck; //works
      (<FaIconComponent>componentRef.instance).ngOnChanges({});
    }
}
4

1 回答 1

2

由于 0.5.0 版本angular-fontawesome对动态渲染图标组件有更好的支持。查看官方文档

@Component({
  selector: 'fa-host',
  template: '<ng-container #host></ng-container>'
})
class HostComponent {
  @ViewChild('host', {static: true, read: ViewContainerRef}) container: ViewContainerRef;

  constructor(private cfr: ComponentFactoryResolver) {
  }

  createIcon() {
    const factory = this.cfr.resolveComponentFactory(FaIconComponent);
    const componentRef = this.container.createComponent(factory);
    componentRef.instance.icon = faUser;
    // Note that FaIconComponent.render() should be called to update the
    // rendered SVG after setting/updating component inputs.
    componentRef.instance.render();
  }
}

是什么原因?我在浏览器中遇到的错误是“FontAwesome:找不到图标。看起来您为此组件提供了一个空或未定义的图标对象。”

因为您应该设置iconProp输入属性,而不是icon属性,它被错误地暴露在组件上。请注意,在 >0.5.0 中不再是这种情况(参见上面的示例)。

最佳做法是什么?

见上面的例子。

为什么我需要在指令 ngOnInit() 挂钩中调用 ngOnChanges()?

因为图标渲染是通过调用ngOnChangeshook触发的,当你在模板中添加组件时,这是由 Angular 框架执行的。动态创建组件时,Angular 不会调用这个钩子,所以需要手动进行。请注意,在 >0.5.0 中有一个专用方法,它可以在不依赖此实现细节的情况下触发渲染 - FaIconComponent.render().

于 2019-08-23T22:56:07.670 回答