How to place a dynamic component in a container

前端 未结 3 1105
面向向阳花
面向向阳花 2020-12-01 03:26

I want to create dynamic components and insert views of these components to a container.

I think this can be achieved by ViewContainerRef.

But I don\'t know,

相关标签:
3条回答
  • 2020-12-01 03:58

    I was searching for a solution to this problem as well.

    The only way I was able to make it happen was to use an additional 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) {
    
        }
    }
    

    It should produce something similar to this.

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

    I'm not sure if my examples are clear or working, feel free to ask questions or make suggestions, I will try to answer and update my example.

    0 讨论(0)
  • 2020-12-01 04:04

    I did something like that for my app. To load datas in a table.

    To do that I've creat a directive :

    directives: [TableDirective]
    

    And then I use it like that :

    @ViewChild(TableDirective) tableDirective:TableDirective;
    
    ngAfterViewInit() {
        setTimeout(_=>this.load());
    }
    
    load() {
        this.tableDirective.loadTable(*ADirectiveToLoad*);
    }
    

    The TableDirective File :

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

    This will load datas in my table, depend of the Directive I send. For exemple :

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

    I'm also new with Angular :x

    0 讨论(0)
  • 2020-12-01 04:12

    You can get the ViewContainerRef of the current component by or from an element in the view of the current component

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

    See also Angular 2 dynamic tabs with user-click chosen components

    0 讨论(0)
提交回复
热议问题