如何知道动态创建的 Angular 组件何时可以在 DOM 中请求?

Posted

技术标签:

【中文标题】如何知道动态创建的 Angular 组件何时可以在 DOM 中请求?【英文标题】:How to know WHEN a dynamically created Angular component is available to request in the DOM? 【发布时间】:2021-08-24 09:45:58 【问题描述】:

我像这样动态创建一个 Angular 组件(代码被简化,有一些缺失的部分):

[...]

@ViewChild(MyDirective,  static: true ) myHost!: MyDirective;

constructor(
    private readonly compiler: Compiler,
    private readonly injector: Injector,
  ) 

[...]

const myModule: typeof MyModule = (
      await import('../../../my/my.module')
    ).MyModule;

const moduleFactory: NgModuleFactory<MyModule> = await this.compiler.compileModuleAsync(
      myModule,
    );


const moduleReference: NgModuleRef<MyModule> = moduleFactory.create(this.injector);


const componentFactory: ComponentFactory<MyComponent> = moduleReference.instance.resolveComponent();
const componentReference: ComponentRef<MyComponent> = myHost.viewContainerReference.createComponent(
      componentFactory,
      undefined,
      moduleReference.injector,
    );

componentReference.instance.item = myItem;    
componentReference.instance.options = myOptions;

// Here I need to wait ~200ms for the component to be available to request in the DOM ... 
await timer(200).toPromise();

const myComponent: Element = document.querySelector('my-component');

// Then I use the component to generate an image with the library html-to-image
const dataUrl: string = await toSvg(myComponent);


return dataUrl;

我必须等待大约 200 毫秒才能让我的组件在 DOM 中可用以请求...否则它返回未定义。我试图在MyComponent 中实现ngAfterViewInit,然后公开一个observable,以便我可以订阅它然后请求它,但它仍然返回未定义。 MyComponent 只有 @Inputs 和一个模板,没有别的。模板看起来像这样:

<ng-container *ngIf="condition; else loading">
  <div prop="stuff | MyPipe">stuff</div>
</ng-container>

<ng-template #loading>
  stuff
</ng-template>

我如何知道动态创建的组件何时可供请求?

【问题讨论】:

【参考方案1】:

我不知道我是否正确理解了您的代码,因为有一些缺失的部分。我认为 MyDirective 是您的锚指令。下面的答案是基于我对您的代码库的理解所做的假设。

您应该使用 ComponentFactoryResolver.resolveComponentFactory() 来解析每个组件的 ComponentFactory。

const componentFactory = this.componentFactoryResolver.resolveComponentFactory("give component name here");

const viewContainerRef = this.directiveName.viewContainerRef; //the directive should inject viewContainerRef to access the view container of the parent component which will host the dynamic components
viewContainerRef.clear(); 

const componentRef = viewContainerRef.createComponent<DynamicComponent>(componentFactory);

在此处了解更多信息https://angular.io/guide/dynamic-component-loader

【讨论】:

感谢您的回复!是的,这是我的锚指令&lt;ng-template myDirective&gt;&lt;/ng-template&gt;;我将尝试您的解决方案并让您知道

以上是关于如何知道动态创建的 Angular 组件何时可以在 DOM 中请求?的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2:向动态创建的组件添加指令

角度 5 延迟加载与动态加载

Angular2动态组件和TP jQuery库

Angular 表单:如何动态添加/删除子表单组件

如何检测 Angular 中的 @Input() 值何时发生变化?

Angular 10:如何创建动态组件/html?