您的位置:首页 > 其它

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

2018-02-09 14:37 429 查看
正常在父组件中使用子组件的方法是如下:

父组件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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: