NG4-详解Angular 4.x 动态创建组件
2017-08-15 10:38
621 查看
动态创建组件
这篇文章我们将介绍在 Angular 中如何动态创建组件。
定义 AlertComponent 组件
首先,我们需要定义一个组件。
exe-alert.component.ts
?
上面代码中,我们定义了一个简单的
DOM 元素,因此如果我们需要在页面中插入该元素,我们就需要考虑在哪里放置该元素。
创建组件容器
在 Angular 中放置组件的地方称为
app.component.ts
?
友情提示:容器可以是任意的 DOM 元素或组件。
在 AppComponent 组件中,我们可以通过
DOM 元素,但这个示例中,我们需要获取
ViewContainerRef 用于表示一个视图容器,可添加一个或多个视图。通过 ViewContainerRef 实例,我们可以基于 TemplateRef 实例创建内嵌视图,并能指定内嵌视图的插入位置,也可以方便对视图容器中已有的视图进行管理。简而言之,ViewContainerRef 的主要作用是创建和管理内嵌视图或组件视图。
根据以上需求,更新后的代码如下:
?
动态创建组件
接下来,在 AppComponent 组件中,我们来添加两个按钮,用于创建 AlertComponent 组件。
?
在我们定义
ComponentFactoryResolver抽象类:
?
在 AppComponent 组件构造函数中,注入ComponentFactoryResolver服务:
?
接下来我们再来看一下 ComponentFactory抽象类:
?
通过观察 ComponentFactory抽象类,我们知道可以通过调用 ComponentFactory实例的
AppComponent 组件的
?
接下来我们来分段解释一下上面的代码。
?
每次我们需要创建组件时,我们需要删除之前的视图,否则组件容器中会出现多个视图 (如果允许多个组件的话,就不需要执行清除操作 )。
复制代码代码如下:
const factory: ComponentFactory= this.resolver.resolveComponentFactory(AlertComponent);
正如我们之前所说的,
复制代码代码如下:
this.componentRef: ComponentRef = this.container.createComponent(factory);
在上面代码中,我们调用容器的
create() 方法创建对应的组件,并将组件添加到我们的容器。
现在我们已经能获取新组件的引用,即可以我们可以设置组件的输入类型:
?
同样我们也可以订阅组件的输出属性,具体如下:
?
另外不能忘记销毁组件:
?
最后我们需要将动态组件添加到 NgModule 的 entryComponents 属性中:
?
完整示例
exe-alert.component.ts
?
app.component.ts
?
app.module.ts
?
总结
获取装载动态组件的容器
在组件类的构造函数中,注入
调用
调用组件容器对象的
基于返回的
(可选)
在模块 Metadata 对象的 entryComponents 属性中添加动态组件
declarations - 用于指定属于该模块的指令和管道列表
entryComponents - 用于指定在模块定义时,需要编译的组件列表。对于列表中声明的每个组件,Angular 将会创建对应的一个 ComponentFactory对象,并将其存储在ComponentFactoryResolver对象中
我有话说
通常情况下,当我们使用结构指令时,我们需要添加额外的标签来封装内容,如使用
?
上面示例中,我们在 section 标签上应用了ngIf指令,从而实现 section 标签内容的动态显示。这种方式有个问题是,我们必须添加额外的 DOM 元素。要解决该问题,我们可以使用<ng-template>的标准语法 (非*ngIf语法糖):
?
问题是解决了但我们不再使用
<ng-container>
DOM 树中的节点,它将被渲染为 HTML中的
?
有时我们需要根据
?
针对这种情况,理论上我们是不需要添加额外的
?
介绍完
?
以上代码运行后,浏览器中输出结果是:
In ng-container, no attributes.
即
?
以上代码运行后,浏览器中输出结果是:
ngIf with a template.
ngIf with an ng-container.
现在我们来总结一下
<ng-template>:使用 *语法糖的结构指令,最终都会转换为<ng-template>或 <template> 模板指令,模板内的内容如果不进行处理,是不会在页面中显示的。
<ng-container>:是一个逻辑容器,可用于对节点进行分组,但不作为 DOM 树中的节点,它将被渲染为 HTML中的 comment元素,它可用于避免添加额外的元素来使用结构指令。
最后再来看一个
模板定义
?
渲染结果
?
TemplateRef 与 ViewContainerRef 有什么作用?
TemplateRef
用于表示内嵌的 template 模板元素,通过 TemplateRef 实例,我们可以方便创建内嵌视图(Embedded Views),且可以轻松地访问到通过 ElementRef 封装后的 nativeElement。需要注意的是组件视图中的 template 模板元素,经过渲染后会被替换成 comment元素。
ViewContainerRef
用于表示一个视图容器,可添加一个或多个视图。通 ViewContainerRef 实例,我们可以基于 TemplateRef 实例创建内嵌视图,并能指定内嵌视图的插入位置,也可以方便对视图容器中已有的视图进行管理。简而言之,ViewContainerRef 的主要作用是创建和管理内嵌视图或组件视图。(本示例就是通过 ViewContainerRef 对象提供的 API来动态地创建组件视图)。
ViewChild装饰器还支持哪些查询条件?
ViewChild装饰器用于获取模板视图中的元素,它支持 Type 类型或 string 类型的选择器,同时支持设置 read 查询条件,以获取不同类型的实例。
?
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
原文链接:https://segmentfault.com/a/1190000009175508
这篇文章我们将介绍在 Angular 中如何动态创建组件。
定义 AlertComponent 组件
首先,我们需要定义一个组件。
exe-alert.component.ts
?
alert组件,该组件有一个输入属性
type,用于让用户自定义提示的类型。我们的自定义组件最终是一个实际的
DOM 元素,因此如果我们需要在页面中插入该元素,我们就需要考虑在哪里放置该元素。
创建组件容器
在 Angular 中放置组件的地方称为
container容器。接下来,我们将在
exe-app组件中创建一个模板元素,此外我们使用模板变量的语法,声明一个模板变量。接下来模板元素
<ng-template>将会作为我们的组件容器,具体示例如下:
app.component.ts
?
在 AppComponent 组件中,我们可以通过
ViewChild装饰器来获取视图中的模板元素,如果没有指定第二个查询参数,则默认返回的组件实例或相应的
DOM 元素,但这个示例中,我们需要获取
ViewContainerRef实例。
ViewContainerRef 用于表示一个视图容器,可添加一个或多个视图。通过 ViewContainerRef 实例,我们可以基于 TemplateRef 实例创建内嵌视图,并能指定内嵌视图的插入位置,也可以方便对视图容器中已有的视图进行管理。简而言之,ViewContainerRef 的主要作用是创建和管理内嵌视图或组件视图。
根据以上需求,更新后的代码如下:
?
接下来,在 AppComponent 组件中,我们来添加两个按钮,用于创建 AlertComponent 组件。
?
createComponent()方法前,我们需要注入
ComponentFactoryResolver服务对象。该
ComponentFactoryResolver服务对象中,提供了一个很重要的方法
- resolveComponentFactory(),该方法接收一个组件类作为参数,并返回
ComponentFactory。
ComponentFactoryResolver抽象类:
?
?
?
create()方法,来创建组件。介绍完上面的知识,我们来实现
AppComponent 组件的
createComponent()方法:
?
?
复制代码代码如下:
const factory: ComponentFactory= this.resolver.resolveComponentFactory(AlertComponent);
正如我们之前所说的,
resolveComponentFactory()方法接受一个组件并返回如何创建组件的
ComponentFactory实例。
复制代码代码如下:
this.componentRef: ComponentRef = this.container.createComponent(factory);
在上面代码中,我们调用容器的
createComponent()方法,该方法内部将调用
ComponentFactory实例的
create() 方法创建对应的组件,并将组件添加到我们的容器。
现在我们已经能获取新组件的引用,即可以我们可以设置组件的输入类型:
?
?
?
?
exe-alert.component.ts
?
?
?
获取装载动态组件的容器
在组件类的构造函数中,注入
ComponentFactoryResolver对象
调用
ComponentFactoryResolver对象的
resolveComponentFactory()方法创建
ComponentFactory对象
调用组件容器对象的
createComponent()方法创建组件并自动添加动态组件到组件容器中
基于返回的
ComponentRef组件实例,配置组件相关属性
(可选)
在模块 Metadata 对象的 entryComponents 属性中添加动态组件
declarations - 用于指定属于该模块的指令和管道列表
entryComponents - 用于指定在模块定义时,需要编译的组件列表。对于列表中声明的每个组件,Angular 将会创建对应的一个 ComponentFactory对象,并将其存储在ComponentFactoryResolver对象中
我有话说
<ng-template>与
<ng-container>有什么区别?
通常情况下,当我们使用结构指令时,我们需要添加额外的标签来封装内容,如使用
*ngIf指令:
?
?
*语法糖语法,这样会导致我们代码的不统一。虽然解决了问题,但又带来了新问题。那我们还有其它的方案么?答案是有的,我们可以使用
ng-container指令。
<ng-container>
<ng-container>是一个逻辑容器,可用于对节点进行分组,但不作为
DOM 树中的节点,它将被渲染为 HTML中的
comment元素。使用
<ng-container>的示例如下:
?
switch语句,动态显示文本,这时我们需要添加一个额外的标签如
<span>,具体示例如下:
?
<span>标签,这时我们可以使用
ng-container来解决这个问题:
?
ng-container指令,我们来分析一下它跟
ng-template指令有什么区别?我们先看以下示例:
?
In ng-container, no attributes.
即
<ng-template>中的内容不会显示。当在上面的模板中添加
ngIf指令:
?
ngIf with a template.
ngIf with an ng-container.
现在我们来总结一下
<ng-template>和
<ng-container>的区别:
<ng-template>:使用 *语法糖的结构指令,最终都会转换为<ng-template>或 <template> 模板指令,模板内的内容如果不进行处理,是不会在页面中显示的。
<ng-container>:是一个逻辑容器,可用于对节点进行分组,但不作为 DOM 树中的节点,它将被渲染为 HTML中的 comment元素,它可用于避免添加额外的元素来使用结构指令。
最后再来看一个
<ng-container>的使用示例:
模板定义
?
?
TemplateRef
用于表示内嵌的 template 模板元素,通过 TemplateRef 实例,我们可以方便创建内嵌视图(Embedded Views),且可以轻松地访问到通过 ElementRef 封装后的 nativeElement。需要注意的是组件视图中的 template 模板元素,经过渲染后会被替换成 comment元素。
ViewContainerRef
用于表示一个视图容器,可添加一个或多个视图。通 ViewContainerRef 实例,我们可以基于 TemplateRef 实例创建内嵌视图,并能指定内嵌视图的插入位置,也可以方便对视图容器中已有的视图进行管理。简而言之,ViewContainerRef 的主要作用是创建和管理内嵌视图或组件视图。(本示例就是通过 ViewContainerRef 对象提供的 API来动态地创建组件视图)。
ViewChild装饰器还支持哪些查询条件?
ViewChild装饰器用于获取模板视图中的元素,它支持 Type 类型或 string 类型的选择器,同时支持设置 read 查询条件,以获取不同类型的实例。
?
原文链接:https://segmentfault.com/a/1190000009175508
相关文章推荐
- 详解Angular 4.x 动态创建组件
- angular学习总结十一——动态创建组件并实现交互二
- 动态创建Angular组件实现popup弹窗功能
- 动态创建angular组件实现popup弹窗
- Angular.js实现动态加载组件详解
- angular学习总结十——动态创建组件并实现交互一
- Qt Quick 组件与对象动态创建详解
- FLEX如何动态创建DataGrid组件详解
- angular 4.*如何创建动态组件
- Qt Quick 组件与对象动态创建详解
- QML 组件与对象动态创建详解
- angular 动态组件类型详解(四种组件类型)
- Angular 4根据组件名称动态创建出组件的方法教程
- angular 动态组件
- Delphi动态创建组件
- 动态创建MFCTabCtrl组件并在其父窗口中捕获,处理消息
- 安卓四大组件之二#1-Service的创建,生命周期以及动态调用Service里的方法 推荐
- Angular2实现父子组件通信(详解)
- Angular动态注册组件(controller,service...)
- angular 创建组件报错