What are projectable nodes in angular2

后端 未结 1 1421
没有蜡笔的小新
没有蜡笔的小新 2020-12-14 20:04

On reading the documentation of ViewContainerRef and ComponentFactory, where , for example we have the method

ViewContainerRef#createComponent which takes 3 argumen

相关标签:
1条回答
  • 2020-12-14 20:52

    Projectable nodes are the node elements ( i.e elements implementing the node interface ), which are "projected" or in other words, transcluded onto the ng-content that we have in the template of our component.

    For example we can create a node element the following way :

    var myNode = document.createElement('div');
    var text = document.createTextNode('this is my text');
    myNode.appendChild(text);
    

    Then we can use the above node, the following way :

    constructor(private vcr:ViewContainerRef ) {
    
    }
    ngAfterViewInit() {
    
      let cmpFactory = this.vcr.resolveComponentFactory(MyDynamicComponent);
      let injector = this.vcr.parentInjector;
    
      var myNode = document.createElement('div');
      var text = document.createTextNode('this is my text');
      myNode.appendChild(text);
      this.vcr.createComponent(cmpFactory,0,injector,[ [ myNode ] ])
    }
    

    A two dimensional array is accepted for projected nodes as we can have multi-slot transclusion, that is more than one ng-content.

    Here is a full example of how to use the projectable nodes with ViewContainerRef#createComponent. This example dynamically creates a component that has transclsion/ng-content in it:

    import { Component, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
    import { ComponentFactory,ComponentRef, Renderer } from '@angular/core';
    
    @Component({
        selector: 'sample',
        template: '<ng-content></ng-content><ng-content></ng-content>'
    })
    export class Sample { }
    
    @Component({
        selector: 'demo',
        template: '<p>Demo</p>',
        entryComponents: [Sample]
    })
    export class DemoComponent {
    
        constructor(private vcr: ViewContainerRef, private cfr: ComponentFactoryResolver, private r: Renderer) { }
    
        ngAfterViewInit() {
            let cmpFactory = this.cfr.resolveComponentFactory(Sample);
            let injector = this.vcr.parentInjector;
            let demoCompEl = this.vcr.element.nativeElement;
    
            let projectedElA = this.r.createElement(demoCompEl,'p');
            this.r.createText(projectedElA,'projectable content A');
            this.r.detachView([projectedElA]);
    
            let projectedElB = this.r.createElement(demoCompEl,'p');
            this.r.createText(projectedElB,'projectable content B');
            this.r.detachView([projectedElB]);
    
            let projectedC = document.createElement('div');
            let text = document.createTextNode('projectable content C');
            projectedC.appendChild(text);
    
            let cmpRef = this.vcr.createComponent(cmpFactory,0,injector,[[projectedElA],[projectedElB,projectedC]]);
    
        }
    
    
    }
    

    Output :

    Demo
    
    projectable content A
    
    projectable content B
    
    projectable content C
    

    The additonal thing to notice is that in the 2d array that we pass for projectable nodes, each 1d array entry has the root elements of a particular view that belong together/ will be rendered together in a single ng-content block

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