Un componente principal que contiene un @ViewChildren no devuelve resultados para los componentes que se crean dinámicamente.
El componente contenedor contiene una directiva de highlight y el componente generado dinámicamente contiene una directiva de highlight dentro de su plantilla. Cuando se consulta con @ViewChildren la longitud de la consulta devuelve 1 . El resultado esperado es 2 .
Como puede ver en el HTML, definitivamente hay dos directivas destacadas en el 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>¿Me estoy perdiendo de algo?
https://plnkr.co/edit/LilvHJgFjPHnPuaNIKir?p=preview
Componente de contenedor
@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); } }componente dinámico
@Component({ selector: 'dynamic-component', template: ` <div highlight>Dynamic!</div> `, }) export class DynamicComponent { }Destacar Directiva
@Directive({ selector: '[highlight]' }) export class HighlightDirective { constructor(private elementRef: ElementRef) { elementRef.nativeElement.style.backgroundColor = 'yellow'; } }Eso no funciona porque @ViewChildren solo consulta su propia vista, no la vista contenida en los componentes secundarios. Su componente dinámico es un componente secundario que tiene su propia vista.
Para evitar esto, puede agregar una consulta @ViewChildren en el componente dinámico que tiene un evento de salida para que cualquier persona interesada (su componente principal) sepa que existe una nueva instancia.