#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-содержимое?