有没有一种以编程方式在Angular中呈现组件的方法?

6

如标题所述,是否有一种方法可以在Angular中以编程方式呈现(到DOM元素)一个组件?

例如,在React中,我可以使用ReactDOM.render将组件转换为DOM元素。 我想知道在Angular中是否也有类似的功能?


2
https://angular.io/guide/dynamic-component-loader - tom10271
你介意解释一下动态组件加载器是如何让我做到这一点的吗? - Semo
3个回答

15

首先,在您希望放置动态加载组件的位置,您需要在HTML文件中拥有一个模板。

<ng-template #placeholder></ng-template>

在组件中,您可以在构造函数中注入DynamicFactoryResolver。一旦执行 loadComponent() 函数,DynamicComponent 就会在模板中可见。 DynamicComponent 可以是您想要显示的任何组件。

import { Component, VERSION, ComponentFactoryResolver, ViewChild, ElementRef, ViewContainerRef } from '@angular/core';
import { DynamicComponent } from './dynamic.component';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html'
})
export class AppComponent  {
  @ViewChild('placeholder', {read: ViewContainerRef})
  private viewRef: ViewContainerRef;

  constructor(private cfr: ComponentFactoryResolver) {}

  loadComponent() {
    this.viewRef.clear();
    const componentFactory = this.cfr.resolveComponentFactory(DynamicComponent);
    const componentRef = this.viewRef.createComponent(componentFactory);
  }
}

这里有一个Stackblitz

loadComponent函数的作用是:

  1. 清除主机中原有的组件(如果有);
  2. 创建所谓的组件工厂对象 (resolveComponentFactory);
  3. 创建组件工厂对象的实例并将其插入到主机中(createComponent);
  4. 您可以使用 componentRef 来修改该组件实例的公共属性或触发公共函数等操作。

ComponentFactoryResolver已被弃用 - undefined

0
如果您想将Angular组件渲染到未经Angular编译的Dom元素中,则无法获取ViewContainerRef。此时,您可以使用Angular cdk portal和portal host概念来实现。 使用任何DOMElememt、injector、applicationRef、componentFactoryResolver创建portal host。 使用组件类创建portal。 并将portal附加到host上。 https://medium.com/angular-in-depth/angular-cdk-portals-b02f66dd020c

1
如果您能添加演示如何实现此操作的代码,而不仅仅是描述它,那么这将改善您的答案。 - Matthew Barlowe
我的公司政策规定不允许添加代码。我已经添加了我阅读到的Medium文章的链接。 - Nanda Kr

0
基于 Felix 的回答,ComponentFactoryResolver 不再需要。因此,简化版本为:
import { Component, VERSION, ViewChild, ElementRef, ViewContainerRef } from '@angular/core';
import { DynamicComponent } from './dynamic.component';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html'
})
export class AppComponent  {
  @ViewChild('placeholder', {read: ViewContainerRef})
  private viewRef: ViewContainerRef;

  loadComponent() {
    this.viewRef.clear();
    const componentRef = this.viewRef.createComponent(DynamicComponent);
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接