Angular2 - Inject Component to Body

Asked

Viewed 1,314 times

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 be 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 with Angular2 do not compile that directive.

1 answer

2

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

To compile the component you need to use the method createComponent class ViewContainerRef contained in@angular/core. This method takes as parameter a ComponentFactory<T> which may be obtained in the following forms:

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

2 - Using any of the methods in the class Compiler ('@angular/core'), the use of compileModuleAndAllComponentsAsync which takes as parameter the module of the component to be "injected".

In short, we can say that the ViewContainerRef would be a reference of where you will inject the component using one of the two forms presented above. You can observe how it would look using 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 the content on the subject (stackoverflow.com links).

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?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.