Angular2 - Inject Component into Body

3

Good afternoon!

I have the following component

import { Component, Input, ElementRef, HostListener, OnDestroy, OnInit } from '@angular/core';
/**
 * This class represents the navigation bar component.
 */

@Component({
  moduleId: module.id,
  selector: 'sd-notification',
  templateUrl: 'notification.component.html',
  styleUrls: ['notification.component.css'],
})
export class NotificationComponent implements OnDestroy, OnInit {

  constructor(private el: ElementRef) { }

  @Input() mensagem: string;
  @Input() time: number = 2000;
  @Input() tipo: string ="";
  isVisible = true;
  ngOnInit() {
    setTimeout(() => {
      this.ngOnDestroy();
    }, this.time);
  }

  ngOnDestroy() {
    this.isVisible = false;
    setTimeout(() => {
      this.el.nativeElement.remove();
    }, 1000);
  }

  private _timeOut: number = 3000;
  public get timeOut(): number {
    return this._timeOut;
  }
  public set timeOut(v: number) {
    this._timeOut = v;
  }

  fechar() {
    this.ngOnDestroy();
  }
}

I want to inject it into another Component, in javascript it would look something like this:

import { Component } from '@angular/core';
/**
 * This class represents the lazy loaded ServicoComponent.
 */
@Component({
  moduleId: module.id,
  selector: 'sd-servico',
  templateUrl: 'servico.component.html',
  styleUrls: ['servico.component.css']
})
export class ServicoComponent {

  constructor(public service: ServicoService) {
  }

  salvar(servico?: Servico) {
    document.body.innerHTML += '<sd-notification tipo="syo-success" mensagem="Dados salvos com sucesso!"></sd-notification>'; // Mas isso não compila a diretiva ds-notification.... 
  }

}

But Angular2 does not compile this directive.

    
asked by anonymous 31.01.2017 / 18:20

1 answer

2

Well, for you to inject this component into another it is necessary to use an angular2 feature that can be seen in detail in link of the official website.

To compile the component you need to use the createComponent method of the ViewContainerRef class contained in '@ angular / core'. This method receives as parameter ComponentFactory<T> which can be obtained in the following ways:

1 - Method resolveComponentFactory of class ComponentFactoryResolver ('@ angular / core') that receives as parameter the type of the component, in its case would be NotificationComponent .

2 - Using one of the methods present in the Compiler ('@ angular / core') class, being more common the use of compileModuleAndAllComponentsAsync that receives as a parameter the component module to be "injected".

In summary, we can say that ViewContainerRef would be a reference of the place where you will inject the component using one of the two forms presented above. You can see how you would use ComponenteFactoryResolver in the example below:

export class InjetorComponent implements AfterViewInit, OnDestroy {

  constructor(private _componentFactoryResolver: ComponentFactoryResolver, private _vcRef: ViewContainerRef) { }

  ngAfterViewInit() {
    this.loadComponent();
  }

  ngOnDestroy() {
      //Destrói todas as views injetadas neste componente.
      this._vcRef.clear();
  }

  loadComponent() {
    let componentFactory = this._componentFactoryResolver.resolveComponentFactory(NotificationComponent);
    let componentRef = this._vcRef.createComponent(componentFactory);
    //Acessando a instancia do componente.
    (<NotificationComponent>componentRef.instance).menssagem = "Menssagem de um componente criado dinamicamente!";
  }
}

Some references to content on the subject (links on stackoverflow.com).

How do I dynamically inject an Angular2 sub component via typescript code?

How can I use / create dynamic template to compile dynamic component with Angular 2.0?

    
01.02.2017 / 12:24