Динамические компоненты в Angular

Sep 2, 2018

В отличие от того же *ngIf, динамические компоненты не указываются в шаблоне вообще.

Как создать динамический компонент в Angular?

Какие шаги нужно сделать, чтобы указать Angular, что компонент будет подгружаться динамически?

1. В модуле указывается свойство NgModule/entryComponents:

entryComponents: {
        TestDynamicComponent
    },    
    declarations: [
        TestDynamicComponent,

2. Далее в том компоненте, где потребуется наш динамический компонент, inject-м следующие сущности:

constructor(
            private viewContainerRef: ViewContainerRef,
            private componentFactoryResolver: ComponentFactoryResolver
         ) {
  • Более подробно о ViewContainerRef в статье Директивы в Angular
  • ComponentFactoryResolver - позволит разрешить (собрать) наш динамический компонент

3. Вставим компонент в шаблон через какое-то время:

ngOnInit() {

    let self = this;
    setTimeout(function () {
        // фабрика для создания компонента (componentFactory)
        const componentFactory = self.componentFactoryResolver.resolveComponentFactory(TestDynamicComponent);
        // создадим компонент внутри контейнера
        const componentRef = self.viewContainerRef.createComponent(componentFactory);
        componentRef.changeDetectorRef.detectChanges();
    }, 3000);

Как расположить динамический компонент в контейнере?

Как расположить динамический компонент в контейнере на stackoverflow

@Component({
    selector: '...',
    directives: [OtherComponent, FooComponent],
    template: `
        <other-component></other-component>
        <foo-component #foo></foo-component>
        <div #div></div>`
})

export class SomeComponent {
    // `ViewContainerRef` from an element in the view
    @ViewChild(OtherComponent, {read: ViewContainerRef}) other;
    @ViewChild('foo', {read: ViewContainerRef}) foo;
    @ViewChild('div', {read: ViewContainerRef}) div;

    // `ViewContainerRef` from the component itself
    constructor(private viewContainerRef:ViewContainerRef, private componentFactoryResolver: ComponentFactoryResolver) {}

    let factory = this.componentFactoryResolver.resolveComponentFactory(ControlBox)
    this.componentRef = this.other.createComponent(factory);
    // this.componentRef = this.foo.createComponent(factory);
    // this.componentRef = this.div.createComponent(factory);
    // this.componentRef = this.viewContainerRef.createComponent(factory);
    });
}

Загружаем динамический компонент при помощи директивы ngComponentOutlet

ngComponentOutlet - директива, которой можно динамически передавать компоненты.

    <!-- в шаблоне: -->
    <div *ngComponentOutlet="myComponentForDynamic"></div>
    export class ItemComponent implements OnInit, AfterContentInit, AfterViewInit {

    public myComponentForDynamic;

    ngOnInit() {

        // вставляем компонент на ngOnInit
        this.myComponentForDynamic = BannerComponent;

        setTimeout(() => {
            // вставляем компонент через 3сек после ngOnInit
            this.myComponentForDynamic = Banner2Component;
        }, 3000);
    }
Добавить комментарий
Комментарии:
jhgc
Mar 27, 2020
kijhgf