ngComponentOutlet: проецируемый контент, определенный в html.
Знаете ли вы, как проецировать контент на выход компонента с контентом, определенным в самом шаблоне?
Я пробовал следующее, но это не работает:
@Component({
template: `<ng-content></ng-content>`,
})
export class MyComp {}
@Component({
selector: 'my-app',
standalone: true,
imports: [CommonModule],
template: `
<div *ngComponentOutlet="cmp">
<div #ref>Ma projection</div> <!-- I'd like to project this -->
</div>
`,
})
export class App {
cmp = MyComp;
}
Я знаю, что могу пройтиcontent
к*ngComponentOutlet
но как я могу передать что-то, что определено в шаблоне, например<div #ref>Ma projection</div>
здесь.
2 ответа
Я придумал следующее решение:
@Component({
selector: 'my-app',
standalone: true,
imports: [CommonModule],
template: `
<h1>Hello from {{name}}!</h1>
<ng-template #ref><div>Ma projection</div></ng-template> <!-- I'd like to project this -->
<div *ngComponentOutlet="cmp"></div>
`,
})
export class App {
name = 'Angular';
cmp = MyComp;
projectables!: any[][];
@ViewChild('ref', { static: true }) template!: TemplateRef<any>;
vcr = inject(ViewContainerRef);
ngOnInit() {
this.projectables = [this.vcr.createEmbeddedView(this.template).rootNodes];
}
}
Я определил шаблон, к которому обращается@ViewChild
.
Когда у меня это будетTemplateRef
вngOnInit
, я создаюViewRef
это мой проецируемый контент.
И вуаля.
Вы можете использовать ViewChild для ссылки на содержимое шаблона, а затем передать его в выход компонента с помощью createEmbeddedView и прикрепить.
import { Component, ViewChild, AfterViewInit, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
template: `<ng-content></ng-content>`,
})
export class MyComp {}
@Component({
selector: 'my-app',
standalone: true,
imports: [CommonModule],
template: `
<div #container></div>
`,
})
export class App implements AfterViewInit {
@ViewChild('container', { read: ViewContainerRef, static: true }) container: ViewContainerRef;
constructor(private cfr: ComponentFactoryResolver) {}
ngAfterViewInit() {
const factory = this.cfr.resolveComponentFactory(MyComp);
const componentRef = this.container.createComponent(factory);
const templateRef = this.container.createEmbeddedView(this.ref.nativeElement);
componentRef.instance.viewRef = templateRef;
componentRef.changeDetectorRef.detectChanges();
this.container.detach();
}
}
ViewChild , чтобы получить ссылку на ViewContainerRef элемента div с переменной шаблона #container. Затем в хуке жизненного цикла ngAfterViewInit мы создаем фабрику компонентов для MyComp и используем ее для создания нового экземпляра компонента. Мы также создаем встроенное представление содержимого, определенное переменной шаблона #ref, с помощью createEmbeddedView, и прикрепляем его к экземпляру компонента с помощью instance.viewRef .
надеюсь, это поможет ..!