ViewChildren doesn't find dynamic components
The parent component containing @ViewChildren does not return results for dynamically created components.
A container component contains a directive highlight
, and a dynamically created component contains a directive highlight
inside this template. When requesting a @ViewChildren
query returns a length 1 . Expected Result: 2 .
As you can see from the HTML, there are definitely two main directives in the DOM.
<container-component>
<div></div>
<dynamic-component ng-version="4.0.0">
<div highlight="" style="background-color: yellow;">Dynamic!</div>
</dynamic-component>
<div highlight="" style="background-color: yellow;">Number of Highlights
<div></div>
</div>
</container-component>
Did I miss something?
https://plnkr.co/edit/LilvHJgFjPHnPuaNIKir?p=preview
Container component
@Component({
selector: 'container-component',
template: `
<div #contentProjection></div>
<div highlight>Number of Highlights {{highlightCount}}<div>
`,
})
export class ContainerComponent implements OnInit, AfterViewInit {
@ViewChildren(HighlightDirective) private highlights: QueryList<HighlightDirective>;
@ViewChild('contentProjection', { read: ViewContainerRef }) private contentProjection: ViewContainerRef;
constructor(
private resolver: ComponentFactoryResolver
) {
}
ngOnInit() {
this.createDynamicComponent();
}
ngAfterViewInit() {
console.log(this.highlights.length);
// Should update with any DOM changes
this.highlights.changes.subscribe(x => {
console.log(this.highlights.length);
});
}
private createDynamicComponent(){
const componentFactory = this.resolver.resolveComponentFactory(DynamicComponent);
this.contentProjection.createComponent(componentFactory);
}
}
Dynamic component
@Component({
selector: 'dynamic-component',
template: `
<div highlight>Dynamic!</div>
`,
})
export class DynamicComponent {
}
Highlight directive
@Directive({
selector: '[highlight]'
})
export class HighlightDirective {
constructor(private elementRef: ElementRef) {
elementRef.nativeElement.style.backgroundColor = 'yellow';
}
}
source to share
This doesn't work because it @ViewChildren
only requests the native view and not the view contained in the child components. Your dynamic component is a child component that has its own look.
To work around this, you can add a request @ViewChildren
to a dynamic component that has an out event so that anyone who cares (your parent component) knows that a new instance exists.
source to share