Подтвердить что ты не робот

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

Я хочу создать динамические компоненты и вставить представления этих компонентов в контейнер.

Я думаю, что это может быть достигнуто ViewContainerRef.

Но я не знаю, можем ли мы получить ViewContainerRef любого компонента? если да, то как?. Я новичок в Angular, если есть какие-либо другие хорошие решения, доступные для обработки этого сценария, пожалуйста, предложите мне.

Обновление Я думаю, я довольно близко к решению. Ниже приведен код.

app.component.ts

import {Component} from '@angular/core';
import {ContainerComponet} from './container.component'

@Component({
    selector: 'my-app',
    template: `
    <container> </container>
    `,
    directives: [ContainerComponet]
})
export class AppComponent {

    constructor() { }

 }

container.component.ts

import {Component, ComponentResolver, ViewContainerRef} from '@angular/core'
import {controlBoxComponent as controlBox} from './controlBox.component';

@Component({
    selector: 'container',
    template: 'container'    
})
export class ContainerComponet {
    constructor(viewContainer: ViewContainerRef, private _cr: ComponentResolver) {

        this._cr.resolveComponent(controlBox)
            .then(cmpFactory => {
                const ctxInjector = viewContainer.injector;
                return viewContainer.createComponent(cmpFactory, 0,  ctxInjector);
            })

    }
}

controlBox.component.ts

import {Component} from '@angular/core'
@Component({
    selector: 'controlBox',
    template: 'controlBox'
})
export class controlBoxComponent {
    constructor() { }
}

Выход

<my-app>
    <container>container</container><controlbox _ngcontent-lsn-3="">controlBox</controlbox>
</my-app>

Ожидаемый результат

<my-app>
    <container>container
    <controlbox _ngcontent-lsn-3="">controlBox</controlbox>
    </container>
</my-app>
4b9b3361

Ответ 1

Вы можете получить ViewContainerRef текущего компонента с помощью или из элемента в представлении текущего компонента

@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);
  });
}

См. также Angular 2 динамических вкладки с выбранными компонентами, выбранными пользователем

Ответ 2

Я сделал что-то подобное для своего приложения. Загрузка данных в таблицу.

Для этого я создаю директиву:

directives: [TableDirective]

И затем я использую его так:

@ViewChild(TableDirective) tableDirective:TableDirective;

ngAfterViewInit() {
    setTimeout(_=>this.load());
}

load() {
    this.tableDirective.loadTable(*ADirectiveToLoad*);
}

Файл TableDirective:

import { Component, DynamicComponentLoader, ViewContainerRef } from 'angular2/core';

@Component({
    selector: "my-table",
    template: `<my-data></my-data>`
})

export class TableDirective {
    constructor(
        private dcl:DynamicComponentLoader,
        private viewContainerRef:ViewContainerRef) {
    }

public loadTable(base:any) {
    this.viewContainerRef.clear();
    this.dcl.loadNextToLocation(base, this.viewContainerRef);
}
}

Это загрузит данные в моей таблице, в зависимости от директивы, которую я отправляю. Например:

import { Component, OnInit } from 'angular2/core';

@Component({
    selector: "my-data",
    templateUrl: "app/_includes/table/actionnaire/table.html"
})

export class ActionnaireDirective implements OnInit {
    private entity:any;

ngOnInit() {
    this.entity = ACTIONNAIRES_PORTEUR;
}
}

var ACTIONNAIRES_PORTEUR:Actionnaire[] = [
    {"id": 1, "nom": "Test", "prenom": "Testeur", "dateNaissance": "15/05/1995"}
];

export class Actionnaire {
    id:number;
    nom:string;
    prenom:string;
    dateNaissance:any;
}

Я также новичок в Angular: x

Ответ 3

Я искал решение этой проблемы.

Единственным способом, которым я смог это сделать, было использование дополнительного Component

import {Component, ViewContainerRef} from '@angular/core';

@Component({
    selector: 'sw-view-container-ref',
    template: `<div></div>`
})

export class SwViewContainerRef {

    private _viewContainerRef:ViewContainerRef;

    constructor(viewContainerRef:ViewContainerRef) {
        this._viewContainerRef = viewContainerRef;
    }

    get viewContainerRef():ViewContainerRef {
        return this._viewContainerRef;
    }
}

container.component.ts

import {Component, ComponentResolver, ViewContainerRef, AfterViewInit, ViewChild,Injector} from '@angular/core'
import {controlBoxComponent as controlBox} from './controlBox.component';
import {SwViewContainerRef} from "./sw-view-container-ref";

@Component({
    selector: 'container',
    template: 'container<sw-view-container-ref #swViewContainerRef></sw-view-container-ref>',
    directives: [SwViewContainerRef]
})
export class ContainerComponet implements AfterViewInit {

    @ViewChild('swViewContainerRef', SwViewContainerRef) swViewChild:SwViewContainerRef;

    ngAfterViewInit() {
        this.desiredViewContainerRef = this.swViewChild.viewContainerRef;

        var self = this;

        this._cr.resolveComponent(controlBox).then((factory) => {

            var componentRef = self.desiredViewContainerRef.createComponent(factory, null, self.injector, null);
            componentRef.changeDetectorRef.detectChanges();
            componentRef.onDestroy(()=> {
                componentRef.changeDetectorRef.detach();
            })

            return componentRef;
        });
    }

    public desiredViewContainerRef:ViewContainerRef;

    constructor(private _cr: ComponentResolver, public injector:Injector) {

    }
}

Он должен создать нечто похожее на это.

<my-app>
<container>container
<sw-view-container-ref><div></div></sw-view-container-ref>
<controlbox>controlBox</controlbox>
</container>
</my-app>

Я не уверен, что мои примеры ясны или работают, не стесняйтесь задавать вопросы или делать предложения, я постараюсь ответить и обновить свой пример.