admin管理员组

文章数量:1332353

Inside global-component I have method for dynamically creating component

const comFactory = this.resolver.resolveComponentFactory(ParentComponent);
const component: any = thisponentContainer.createComponent(comFactory);

(where componentContainer is ViewContainerRef)

Inside my parent-component I have child-component (which has two more child components inside):

<child-component #childCmp></child-component>

Is there any way I can access child-component from my global component?

Inside global-component I have method for dynamically creating component

const comFactory = this.resolver.resolveComponentFactory(ParentComponent);
const component: any = thisponentContainer.createComponent(comFactory);

(where componentContainer is ViewContainerRef)

Inside my parent-component I have child-component (which has two more child components inside):

<child-component #childCmp></child-component>

Is there any way I can access child-component from my global component?

Share Improve this question edited Nov 21, 2024 at 9:19 Sara asked Nov 20, 2024 at 23:13 SaraSara 7513 silver badges14 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

The code explanation is given below, but for latest angular version there is a lot of code that uses deprecated method, so this is the latest way of achieving the same.

import {
  Component,
  ComponentRef,
  createComponent,
  QueryList,
  ViewChildren,
  Injector,
  EnvironmentInjector,
  ApplicationRef,
} from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';

@Component({
  selector: 'app-child',
  standalone: true,
  template: `
        child
      `,
})
export class ChildComponent {
  name = 'Angular';
}

@Component({
  selector: 'app-parent',
  imports: [ChildComponent],
  standalone: true,
  template: `
        <app-child/>
        <app-child/>
      `,
})
export class ParentComponent {
  @ViewChildren(ChildComponent) childs!: QueryList<ChildComponent>;
  name = 'Angular';
}

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
        <a target="_blank" href="https://angular.dev/overview">
          Learn more about Angular
        </a>
      `,
})
export class App {
  component: ComponentRef<ParentComponent>;

  constructor(
    private appRef: ApplicationRef,
    private injector: EnvironmentInjector
  ) {
    thisponent = createComponent(ParentComponent, {
      environmentInjector: this.injector,
    });
    document.body.appendChild(thisponent.location.nativeElement);
    this.appRef.attachView(thisponent.hostView);
  }

  ngAfterViewInit() {
    const childViewChildren: QueryList<ChildComponent> =
      thisponent.instance.childs;
    console.log(childViewChildren);
  }
}

bootstrapApplication(App);

Stackblitz Demo

Getting to Know the createComponent API in Angular - Netanel Basal


You can take a viewChildren of the child component, inside the parent.

...
export class ParentComponent {
  @ViewChildren(ChildComponent) childs: QueryList<ChildComponent>;
  ...
}

Then in the global component declare the component initialization inside the constructor. So that the child elements are available in the ngAfterViewInit hook call.

export class App {
  component: ComponentRef<ParentComponent>;
  
  constructor(
    private resolver: ComponentFactoryResolver,
    private componentContainer: ViewContainerRef
  ) {
    const comFactory = this.resolver.resolveComponentFactory(ParentComponent);
    thisponent = thisponentContainer.createComponent(comFactory);
  }

Also note that I am storing the component reference as a class property so that it can be access on ngAfterViewInit. So when we access the children it will be accessible.

  ngAfterViewInit() {
    const childViewChildren: QueryList<ChildComponent> =
      thisponent.instance.childs;
  }

Full Code:

import {
  Component,
  ComponentFactory,
  ComponentFactoryResolver,
  ComponentRef,
  QueryList,
  ViewChildren,
  ViewContainerRef,
} from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';

@Component({
  selector: 'app-child',
  standalone: true,
  template: `
    child
  `,
})
export class ChildComponent {
  name = 'Angular';
}

@Component({
  selector: 'app-parent',
  imports: [ChildComponent],
  standalone: true,
  template: `
    <app-child/>
    <app-child/>
  `,
})
export class ParentComponent {
  @ViewChildren(ChildComponent) childs!: QueryList<ChildComponent>;
  name = 'Angular';
}

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <a target="_blank" href="https://angular.dev/overview">
      Learn more about Angular
    </a>
  `,
})
export class App {
  component: ComponentRef<ParentComponent>;

  constructor(
    private resolver: ComponentFactoryResolver,
    private componentContainer: ViewContainerRef
  ) {
    const comFactory = this.resolver.resolveComponentFactory(ParentComponent);
    thisponent = thisponentContainer.createComponent(comFactory);
  }

  ngAfterViewInit() {
    const childViewChildren: QueryList<ChildComponent> =
      thisponent.instance.childs;
  }
}

bootstrapApplication(App);

Stackblitz Demo

本文标签: Access child component from dynamically created componentAngular 12Stack Overflow