实现 

模拟场景:页面上"帮助"按钮的点击触发帮助文档的弹出框,且每个页面的帮助文档不一样

因此弹出框里的帮助文档是一个动态模板而不是动态组件

以下comp均代表Type类型的动态组件,即 comp:Type<any>

//xx.component.ts

export class xxComponent implements Oninit{
constructor(private helpingService:HelpingService){ }
fireClick($event:any){//按钮的点击事件
this.helpingService.changeHelpContent(comp);
}
}
//helping.service.ts
@Injectable()
export class HelpingService{
helpChangeEvent:EventEmitter<comp>;
constractor(){
this.helpChangeEvent=new EventEmitter<comp>()
}
public changeHelpContent(comp){
this.helpChangeEvent.emit(comp)//发射helpChangeEvent事件
}
}
//helping.component.ts

@component({
selector: 'helping',
templateUrl: './helping.component.html',
styleUrls: ['./helping.component.scss']
}) @ViewChild('con',{read:ViewContainerRef})
conRef:ViewContainerRef; export class HelpingComponent implements OnInit{
constractor(private helpingService:HelpingService,
private factoryResolver: ComponentFactoryResolver,){
this.helpingService.helpchangeEvent.subscribe((comp)=>{//接收helpChangeEvent事件
this.loadComponent(comp)
})
}
private loadComponent(comp){
this.conRef.clear();//删除之前的视图
let factory=this.factoryResolver.resolveComponentFactory(comp);//factory创建组件的实例
this.conRef.createComponent(factory)
}
}

动态创建组件的相关知识点

1.TemplateRef

通过TemplateRef实例,可以创建内嵌视图Embedded Views

涉及对象和相关方法:

1.crateEbeddedView创建内嵌视图

@Component({
selector:'helping',
template:`//创建组件,那组件内容就是固定的
<template #tpl>
<span>i am a span in Template {{name}}</span>
</template>
`
})
export class helpingComponent{
@ViewChild('tpl')
tpl:TemplateRef<any>; name:string='Artimis'; ngAfterViewInit(){
let view=this.tpl.createEmbeddedView(null);
let commentEle=this.tpl.elementRef.nativeElement;
view.rootNodes.forEach((node)=>{//没有ViewContainerRef,只能手动把元素塞到视图里
commentEle.parentNode.insertBefore(node,commentEle.nextSibling)
})
}
}

2.VIiewContainerRef

视图容器,是管理创建好的内嵌视图或组件视图

通过ViewContainerRef实例,基于TemplateRef + createEmbeddedView创建内嵌视图

@Component({
selector:'helping',
template:`
<template #tpl>
<span>i am a span in Template {{name}}</span>
</template>
`
})
export class helpingComponent{
@ViewChild('tpl')
tpl:TemplateRef<any>; @ViewChild('tpl',{read:ViewContainerRef})
tplVcRef:ViewContainerRef; name:string='Artimis'; ngAfterViewInit(){
//有ViewContainerRef,直接通过createEmbeddedView方法塞进视图
this.tplVcRef.createEmbeddedView(this.tplRef)
}

 动态创建模板的相关知识点

1.ComponentFactoryResolver

通过ViewContainerRef实例,基于ComponentFactoryResolver + createComponent 创建模板视图

涉及对象和相关方法:

1. ComponentFactoryResolver:一个服务对象(需要注入)

2. resolveComponentFactory:ComponentFactoryResolver的方法,接收一个组件类作为参数,返回一个ComponentFactory实例

3.createComponent:ViewContainerRef的方法,内部会调用ComponentFactory实例的create方法创建对应组件,并将组件添加到容器内

export abstract class ComponentFactoryResolver{
static NULL:ComponentFactoryResolver=new _NullComponentFactoryResolver();
abstract resolverComponentFactory<T>(component:Type<T>):ComponentFactory<T>
}
@Component({
selector:'helping',
template:`//创建模板,那模板的内容就不是固定的
<ng-container #con></ng-container>
`
})
export class helpingComponent{ @ViewChild('con',{read:ViewContainerRef})
conRef:ViewContainerRef; constractor(private factoryResolver: ComponentFactoryResolver,
private helpingService: HelpingService){
this.helpingService.manualChange.subscribe((comp)=>{
this.loadComp(comp);
}) private loadComp(comp){
this.conRef.clear();//删除之前的视图
let factory=this.factoryResolver.resolveComponentFactory(comp);//factory是一个如何创建组件的实例
this.conRef.createComponent(factory)
}
}

  

angular4 动态创建组件 vs 动态创建模板的更多相关文章

  1. Java 动态编译组件 & 类动态加载

    1.JDK6 动态编译组件 Java SE 6 之后自身集成了运行时编译的组件:javax.tools,存放在 tools.jar 包里,可以实现 Java 源代码编译,帮助扩展静态应用程序.该包中提 ...

  2. Delphi 动态创建组件,单个创建、单个销毁

    效果图如下: 实现部分代码如下: var rec: Integer = 0; //记录增行按钮点击次数 implementation {$R *.dfm} //动态释放单个组件内存,即销毁组件 pro ...

  3. vue 动态创建组件(运行时创建组件)

    function mountCmp (cmp, props, parent) { if (cmp.default) { cmp = cmp.default } cmp = Vue.extend(cmp ...

  4. Angular 创建组件

    创建组件 0 命令创建 1 创建组件 定义hello.component.ts组件 在app.module.ts中引用并添加到declarations声明中 在app.component.html中使 ...

  5. ionic小白的学习路之目录结构分析、创建组件、创建页面、页面跳转

    一. 目录结构分析 hooks:编译cordova 时自定义的脚本命令,方便整合到我们的编译系统和版本控制系统中. node_modules :node 各类依赖包. resources :andro ...

  6. Angular动态创建组件之Portals

    这篇文章主要介绍使用Angular api 和 CDK Portals两种方式实现动态创建组件,另外还会讲一些跟它相关的知识点,如:Angular多级依赖注入.ViewContainerRef,Por ...

  7. 动态创建组件TEdit

    //动态创建组件TEdit procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;  Shift: TShiftSt ...

  8. Delphi动态创建组件,并释放内存

    开发所用delphi版本是xe2,效果图如下: 代码如下: ---------------------------------------------------------------------- ...

  9. Qt Quick 组件和动态创建的对象具体的解释

    在<Qt Quick 事件处理之信号与槽>一文中介绍自己定义信号时,举了一个简单的样例.定义了一个颜色选择组件,当用户在组建内点击鼠标时,该组件会发出一个携带颜色值的信号,当时我使用 Co ...

随机推荐

  1. redis笔记_源码_内存分配

    文件:zmoalloc.h zmoalloc.c 1.求两个整数的余数 eg: 求_n对sizeof(long)的余数(_n&(sizeof(long)-1)), 性能提升为50%-100% ...

  2. codeforces 1131D-Gourmet choice

    传送门:QAQQAQ 题意:有两个数组,一个数组有n个数,另一个数组有m个数.s[i][j]表示第一个数组第i个数和第二个数组第j个数的大小关系,要求构造出一种方案,使条件成立. 先考虑没有等于号的情 ...

  3. 解决pycharm安装python库报错问题

    最近在玩微信图灵机器人,不过我安装有一些库,安装报错,上网找了很久,总结有两种方法,记录一下 方法一: 手动安装,直接到官网你需要的python库下载到本地, 放在安装python路径,C:\User ...

  4. gatekeeper学习概述

    1.概述 该产品部署在网络隔离装置两端,以代理程序的身份,完成两侧设备连接维护,数据转发的功能.场景简化如图所示: 软件核心是一个基于Netty的网络应用程序,考虑到系统的可维可测性,集成了web化的 ...

  5. TCP重传机制的学习应用

    1. TCP重传机制 TCP协议是一个可靠的协议.发送方每次发送一个数据包,需要等到ACK确认包再继续发送. 发出去的请求包在规定时间内没有收到ACK,不管是请求包丢失,还是ACK包丢失,还是网络延迟 ...

  6. java基础温习 -- Thread synchronized关键字

    synchronized 基本规则 1. 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的该“synchronized方法”或 ...

  7. ElasticSearch入门介绍之会当凌绝顶(一)

    ElasticSearch也是一款非常优秀的开源的全文检索框架,以大名鼎鼎的Apache Lucene为基础,高度封装了更丰富,易用的API,同时与Apache Solr一样,提供了非常强大的分布式集 ...

  8. JS实用插件

    1. jQuery鼠标滚轮事件插件Mouse Wheel 下载链接:https://github.com/brandonaaron/jquery-mousewheel/ 使用方法: // using ...

  9. Web API 接口说明文档

    1.采用 Web API Help Page 显示效果 2.swaggerui 创建文档接口 效果图 3.swagger ui 安装配置 nuget 安装 2.设置xml文件 3.配置根路径 预览sw ...

  10. JavaSE_07_Collection接口的List和Set

    1.1 List接口介绍 java.util.List接口继承自Collection接口,是单列集合的一个重要分支 List接口特点: 它是一个元素存取有序的集合.例如,存元素的顺序是1.2.3.那么 ...