angular中动态创建组件(一)

最近做东西用到了大量动态组件相关的知识,先总结一下一种比较简单的。

已经有了一个组件,AppComponent,也有一个将要动态创建的组件MsgComponent,

@Component({
  selector: 'msg',
  template: `
      <h3>{{type}}</h3>
  `
})
export class MsgComponent {
  type = '123';
}

那么就得有个地方“放”这个动态创建出来的组件,这个地方就叫做容器(container),AppComponent中的容器是这样子的:

template: `
    <h1 #msgContainer>我是Container</h1>
  `,

然后在AppComponent中拿到这个容器:

  @ViewChild('msgContainer', {read: ViewContainerRef}) container;

ViewChild挺强大的;参数设置成ViewContainerRef用来控制container这个变量的类型,视图容器类型。
ViewContainerRef的文档在这里

https://angular.io/api/core/ViewContainerRef

abstract class ViewContainerRef {
  ...
  abstract createComponent<C>(componentFactory: ComponentFactory<C>, index?: number, injector?: Injector, projectableNodes?: any[][], ngModule?: NgModuleRef<any>): ComponentRef<C>
  ...
}

如此一来,container这个实例上就可使用createComponent方法来创建组件了。这个方法的参数比较多,但是只有第一个参数是必须的,别的我也没用过。

第一个参数是一个ComponentFactory的实例,

打一个比喻:container好比是一个小程序员,他有写代码的能力,这个能力叫做createComponent,但是他不知道具体怎么写,他得看需求文档,这个文档就是一个ComponentFactory实例。如何得到这个实例?

组件工厂解析器:ComponentFactoryResolver
组件工厂解析器可以产生一个组件工厂(ComponentFactory),在AppComponent中通过依赖注入获得一个组件工厂解析器:

constructor(private resolver: ComponentFactoryResolver) {
  }

然后就可以创建一个组件工厂,之后交给容器根据这个工厂来创建组件:

const factory: ComponentFactory<MsgComponent> = this.resolver.resolveComponentFactory(MsgComponent);
this.componentRef = this.container.createComponent(factory);

AppComponent的代码如下:

@Component({
  selector: 'my-app',
  template: `
    <h1 #msgContainer>我是Container</h1>
    <button (click)="createComponent()">来一个</button>
  `,
  entryComponents: [MsgComponent], // 或者加到模块中也可以
})
export class AppComponent {
  @ViewChild('msgContainer', {read: ViewContainerRef}) container;
  componentRef: ComponentRef<MsgComponent>;

  constructor(private resolver: ComponentFactoryResolver) {
  }

  createComponent() {
    const factory: ComponentFactory<MsgComponent> = this.resolver.resolveComponentFactory(MsgComponent);

    this.componentRef = this.container.createComponent(factory); // Internally this method will call the create() method from the factory and will append the component as a sibling to our container.

    console.log('componentRef',this.componentRef);

    this.componentRef.instance.type = Math.random() + '';
  }
}

通过componentRef就可以拿到新建的组件实例了:
这里写图片描述

这里写图片描述
从上图中可以看到,新的组件被追加到了容器中,如果希望清空容器,可以创建组件之前调用:

   this.container.clear();

参考文献:
https://netbasal.com/dynamically-creating-components-with-angular-a7346f4a982d

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个Angular的动态组件示例,该组件可以根据输入的组件类型动态创建并显示组件: app.component.ts ``` import { Component, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core'; import { DynamicComponent } from './dynamic.component'; @Component({ selector: 'app-root', template: ` <div #container></div> <button (click)="createComponent('dynamic')">Create Dynamic Component</button> `, }) export class AppComponent { @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef; constructor(private resolver: ComponentFactoryResolver) {} createComponent(type: string) { // 根据组件类型获取组件工厂 const factory = this.resolver.resolveComponentFactory(DynamicComponent); // 创建组件实例 const componentRef = this.container.createComponent(factory); // 设置组件属性 componentRef.instance.type = type; } } ``` dynamic.component.ts ``` import { Component, Input } from '@angular/core'; @Component({ selector: 'app-dynamic', template: ` <div *ngIf="type"> Dynamic Component Type: {{ type }} </div> `, }) export class DynamicComponent { @Input() type: string; } ``` 在这个例子,我们首先在`AppComponent`使用`ViewChild`获取了一个`ViewContainerRef`引用,这个`ViewContainerRef`表示了一个可以动态添加组件的容器。然后,我们在`createComponent`方法根据输入的组件类型获取了一个组件工厂,并使用`createComponent`方法创建了一个组件实例,并将其添加到了容器。最后,我们还在`DynamicComponent`添加了一个`Input`属性`type`,用于接收传递进来的组件类型。 使用这个动态组件的示例可以参考以下内容: ``` <app-root></app-root> ``` 在页面添加了一个按钮,当点击按钮时,会调用`AppComponent`的`createComponent`方法创建一个`DynamicComponent`实例,并将其添加到页面的容器。这个`DynamicComponent`实例会根据传递进来的组件类型显示不同的内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值