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';
      }
    }

      

+3


source to share


1 answer


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.

+3


source







All Articles