8、组件高级玩法:动态组件

正常在父组件中使用子组件的方法是如下:
父组件html模板代码中:

<!--前面的内容-->
...
<child-component></child-component><!--这里直接插入子组件标签,然后标签里面的内容都是固定的-->
...
<!--后面的内容-->

但是如果我们不想这样固定地插入子组件,而是想通过代码动态地创建该如何进行呢?

下面就介绍用代码动态创建组件
直接看代码:
首先子组件的ts组件类代码:

import { Component, OnInit,Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'child11',
  templateUrl: './child11.component.html',
  styleUrls: ['./child11.component.scss']
})
export class Child11Component implements OnInit {
  // 这里是否使用Input装饰器都没有关系,因为待会会看到在父组件中,并不是通过组件局部变量给子组件传递数据的,而是通过代码创建子组件然后获取子组件实例并且赋值传递数据的
  @Input()
  public title:string="默认的标题";

  @Output()
  btnClick:EventEmitter<string>=new EventEmitter<string>();

  constructor() { }

  ngOnInit() {
  }

  // 这里是按钮触发的点击事件,可以手动emit自定义的btnClick事件,可以在父组件中使用describe接收到
  public triggerEvent():void{
    this.btnClick.emit("第一个子组件的点击事件...");
  }
}

随后子组件中的html模板代码:

<div class="panel panel-primary">
    <!--这里使用到了定义的title属性,可以在父组件中通过代码获取到子组件实例,然后赋值的方式获取-->
  <div class="panel-heading">{{title}}</div>
  <div class="panel-body">
    <!--事件绑定-->
    <button class="btn btn-success" (click)="triggerEvent()">触发事件</button>
  </div>
</div>

然后查看父组件的html模板代码,以及如何使用子组件的:

<div class="panel panel-primary">
  <div class="panel-heading">这是父组件</div>
  <div class="panel-body">
    <!--给这个div设置组件局部变量,然后在组件ts代码中可以用到,代码创建的子组件就可以插入到这个标记的地方-->
    <div #dyncomp></div>
    <!--事件绑定-->
    <button class="btn btn-danger" (click)="destoryChild()">销毁子组件</button>
  </div>
</div>

最后查看父组件的组件类ts代码,具体是如何通过代码创建子组件的:

// 1,首先,要使用代码创建子组件的话,需要导入ViewContainerRef和ComponentFactoryResolver和ComponentRef这几个工具类
import { Component, OnInit,ViewChild,ViewContainerRef,ComponentFactoryResolver, ComponentRef } from '@angular/core';
import { Child11Component } from './child11/child11.component';
import { state } from '@angular/animations';

@Component({
  selector: 'dynamic-comp',
  templateUrl: './dynamic-comp.component.html',
  styleUrls: ['./dynamic-comp.component.scss']
})
export class DynamicCompComponent implements OnInit {
  // 2,我们需要使用@ViewChild声明一下,你的子组件需要放在哪里?我们声明的时候就需要用到html中定义的局部变量了
  @ViewChild("dyncomp",{read:ViewContainerRef})
  dyncomp:ViewContainerRef;

  comp1:ComponentRef<Child11Component>;
  comp2:ComponentRef<Child11Component>;

  // 3,我们需要注入resolver这个实例,后面代码创建子组件需要使用这个实例的resolveComponentFactory方法
  constructor(
    private resolver:ComponentFactoryResolver) {

  }

  ngOnInit() {
  }

  ngAfterContentInit(){
    console.log("动态创建组件的实例...");
    // 4,使用resolver实例的resolveComponentFactory方法创建一个工厂
    const childComp=this.resolver.resolveComponentFactory(Child11Component);
    // 5,使用工厂和createComponent方法穿件子组件
    this.comp1=this.dyncomp.createComponent(childComp); 
    // 6,随后可以通过子组件的instance设置对应的属性、获取对应的事件(可以通过事件的subscribe接收)
    // this.comp1.instance.title="父层设置的新标题";

    // this.comp1.instance.btnClick.subscribe((param)=>{
    //   console.log("--->"+param);
    // });

    //可以创建多个组件实例出来
    // let temp1=this.dyncomp.createComponent(childComp); 
    // temp1.instance.title="第2个动态子组件";
    // let temp2=this.dyncomp.createComponent(childComp); 
    // temp2.instance.title="第3个动态子组件";
    // let temp3=this.dyncomp.createComponent(childComp); 
    // temp3.instance.title="第4个动态子组件";
    // let temp4=this.dyncomp.createComponent(childComp); 
    // temp4.instance.title="第5个动态子组件";
    // let temp5=this.dyncomp.createComponent(childComp);
    // temp5.instance.title="第6个动态子组件"; 

    /**
     * createComponent方法可以调用很多次,会动态创建出多个组件实例
     * 方法有第二个参数,表示组件渲染的顺序
     */
    this.comp2=this.dyncomp.createComponent(childComp,0);
    this.comp2.instance.title="第二个子组件";
  }

  public destoryChild():void{
    this.comp1.destroy();
    this.comp2.destroy();
  }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值