Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loading Mat Icon from a directive Angular

I'm having difficultly loading the icon component from Angular Material. What I'm trying to achieve is attach a clickable icon which clears the input using a directive like so.

<input appClearInput></input>

The problem is the component itself is loaded into the template with the proper material classes however the SVG isn't rendered. The icon's functionality and positioning is fine but problem is that the SVG isn't added inside the component therefore it appears blank.

Here is the code inside my directive:

import { Directive, Renderer2, ElementRef, OnInit, ViewContainerRef, ComponentFactoryResolver, ChangeDetectorRef } from '@angular/core';
import { NgControl } from '@angular/forms';
import { MatIcon } from '@angular/material';

@Directive({
  selector: '[appClearInput]'
})
export class ClearInputDirective implements OnInit {
  constructor(
    private elementRef: ElementRef,
    private renderer: Renderer2,
    private control: NgControl,
    private factory: ComponentFactoryResolver,
    private vcRef: ViewContainerRef
} {}

ngOnInit() {
  this.createComponent();
}

createComponent() {
    this.vcRef.clear();

    const factory = this.factory.resolveComponentFactory(MatIcon);
    const matIcon = this.vcRef.createComponent(factory);
    matIcon.instance.svgIcon = 'icon-cross';

    const matIconEl = matIcon.injector.get(MatIcon)._elementRef.nativeElement;
    this.renderer.setAttribute(matIconEl, 'svgIcon', 'icon-cross');
    this.renderer.setStyle(matIconEl, 'cursor', 'pointer');
    this.renderer.setStyle(matIconEl, 'outline', 'none');
    this.renderer.listen(matIconEl, 'click', (e) => this.control.reset());

    const parent = this.elementRef.nativeElement.parentNode;
    const parentParent = this.renderer.parentNode(parent);

    this.renderer.appendChild(parentParent, matIconEl);
  }

I assume it doesn't work because I'm configuring the component after it has been instantiated and doesn't render the component again. If I log the ComponentRef under instance._iconRegistry the list of icons are there.

Appreciate any help, thanks.

like image 844
xzelotl Avatar asked Feb 17 '26 07:02

xzelotl


1 Answers

All you have to do is set the innerHTML on the icon

const searchIcon = this.viewContainer.createComponent<MatIcon>(searchIconResolver);
searchIcon.instance._elementRef.nativeElement.innerHTML = 'search';
like image 160
Jared Beach Avatar answered Feb 19 '26 21:02

Jared Beach



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!