简体   繁体   中英

ViewChildren not finding Dynamic Components

A parent component that contains a @ViewChildren is not returning results for components that are created dynamically.

The container component contains a highlight directive, and the dynamically generated component contains a highlight directive within it's template. When queried with @ViewChildren the query length returns 1 . The expected result is 2 .

As you can see from the HTML there are definitely two highlight directives on 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>

Am I missing 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';
      }
    }

That doesn't work because @ViewChildren only queries its own view, not the view contained within child components. Your dynamic component is a child component that has its own view.

To get around this you could add a @ViewChildren query in the dynamic component that has an output event to let anyone who cares (your parent component) know that a new instance exists.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM