Что такое проецируемые узлы в angular2

#angular #typescript

#angular #typescript

Вопрос:

При чтении документации ViewContainerRef и ComponentFactory, где, например, у нас есть метод

ViewContainerRef#createComponent, который принимает 3 аргумента : componentFactory , injector и projectableNodes .

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

При поиске diff для директивы for ngComponentOutlet все, что я смог собрать, это то, что строка в projectableNodes «проецируется» или отображается в представлении созданных компонентов (например, ng-content может быть). Если это так, это сбивает с толку, поскольку у нас есть ViewContainerRef#createEmbeddedView для того же.

Я хотел бы знать, что это такое projectedNodes , и привести пример их использования.

Комментарии:

1. Я предполагаю, что это то, что обычно отображается в <ng-content> — transcluded elements — но я сам еще не пробовал.

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

Ответ №1:

Проецируемые узлы — это элементы узла (т.Е. Элементы, реализующие интерфейс узла), которые «проецируются» или, другими словами, ng-content переносятся на то, что у нас есть в шаблоне нашего компонента.

Например, мы можем создать элемент узла следующим образом :

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

Затем мы можем использовать вышеупомянутый узел следующим образом :

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

Для проецируемых узлов принимается двумерный массив, поскольку у нас может быть трансклюзия с несколькими слотами, то есть более одного ng-content .

Вот полный пример того, как использовать проецируемые узлы с. ViewContainerRef#createComponent В этом примере динамически создается компонент, в котором содержится transclsion / ng-content:

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

    }


}
  

Вывод :

 Demo

projectable content A

projectable content B

projectable content C
  

Дополнительная вещь, на которую следует обратить внимание, это то, что в 2d-массиве, который мы передаем для проецируемых узлов, каждая запись 1d массива содержит корневые элементы определенного представления, которые принадлежат друг другу / будут отображаться вместе в одном ng-content блоке

Комментарии:

1. Очень хорошо, но кажется, что он компилирует проецируемый элемент (и его дочерние элементы). Как скомпилировать это ng-содержимое?