I have some components that are compiled dynamically using the resolveComponentFactory
.
I do this like so....
const embeddedComponentElements = this.hostElement.querySelectorAll( selector );
const element = embeddedComponentElements[ 0 ];
// convert NodeList into an array, since Angular doesn't like having a NodeList passed
const projectableNodes = [
Array.prototype.slice.call(element.childNodes),
];
const factory = componentFactoryResolver.resolveComponentFactory( Component );
const embeddedComponent = factory.create(
this.injector,
projectableNodes,
element,
);
But I have a problem that i'm struggling to solve....
This works as expected
<div>
<ng-content></ng-content>
</div>
This does NOT work as expected:
<div>
<!-- I get all the content here -->
<ng-content select="h1"></ng-content>
</div>
<div>
<!-- I don't get any content here -->
<ng-content></ng-content>
</div>
It seems that the ng-content
select attribute does not work with dynamically compiled content.
Any ideas what I'm doing wrong or is this a bug?
I'm using Angular 8 if that helps.
Update: I've reproduced this issue in stackBlitz here: https://stackblitz.com/edit/angular-ivy-givxx6
Thanks Poul. Your response helped me a lot. I wrote the below and my unit tests confirm it all now works as expected.
const projectableNodes = this.getNgContent( element, factory.ngContentSelectors );
private getNgContent( element: Element, ngSelectors: string[] ) {
// select the content
const elements = ngSelectors
.map ( s => {
if ( s !== '*' ) {
const els = element.querySelectorAll( s );
els.forEach( e => e.remove() );
return Array.from( els );
}
return s;
});
// where content has not been selected return remaining
return elements.map( s => {
if ( s === '*' ) {
return Array.from( element.childNodes )
}
return s;
});
}