动态组件
1、组件的模板不会永远是固定的。
2、应用可能会需要在运行期间加载一些新的组件。
3、展示如何使用ComponentFactoryResolver 来动态添加组件。
有两个场景 ——
eg1:假设正在计划一个广告活动,要在广告条中显示一系列不同的广告。几个不同的小组可能会频繁加入新的广告组件。
eg2:用户拖动相关的块到特定区域,区域中便会生成相应的UI控件,此UI控件有自己的模板、行为等等。生成UI 后便会在区域中显示出来。将UI控件封为一个小组件,再动态加载是个不错的方案。
!!!此时再用只支持静态组件结构的模板显然是不现实的。需要一种新的组件加载方式,它不需要在广告条组件的模板中引用固定的组件。Angular 自带的API 就能支持动态加载组件。
指令
在添加组件之前,先要定义一个锚点来告诉Angular 要把组件插入到什么地方。
广告条使用一个名叫AdDirective 的辅助指令来在模板中标记出有效的插入点。
AdDirective 注入了ViewContainerRef 来获取对容器视图的访问权,这个容器就是那些动态加入的组件的宿主。
在@Directive 装饰器中,要注意选择器的名称:appAd,它就是将应用到元素上的指令。
加载组件
广告条的大部分实现代码都在 ad-banner.component.ts 中。 这里为了方便HTML 被直接放在了 @Component 装饰器的 template 属性中。(拓展:@Component 元数据的属性)
<ng-template> 元素就是刚才制作的指令将应用到的地方。 要应用 AdDirective,回忆一下来自 ad.directive.ts 的选择器 appAd。把它应用到 <ng-template>(不用带方括号)。 这下,Angular 就知道该把组件动态加载到哪里了。
<ng-template>用于定义模板,使用*语法糖的结构指令,最终都会转换为<ng-template> 模板指令,ng-template元素是动态加载组件的最佳选择,因为它不会渲染任何额外的输出。模板内的内容如果不进行处理,是不会在页面中显示。
解析组件
认识interface:
声明接口
typescript声明合并简单介绍:https://www.tslang.cn/docs/handbook/declaration-merging.html
先简单了解angular2 中相关的api:
ð ViewChild:一个属性装饰器,用来从模板视图中获取对应的元素,可以通过模板变量获取,获取 时可以通过read 属性设置查询的条件,就是说可以把此视图转为不同的实例
ð ViewContainerRef:一个视图容器,可以在此上面创建、插入、删除组件等等
ð ComponentFactoryResolve:一个服务,动态加载组件的核心,这个服务可以将一个组件实例呈现到另一个组件视图上
有了这三个,一个简单的思路便连贯了:特定区域就是一个视图容器,可以通过ViewChild 来实现获取和查询,然后使用ComponentFactoryResolve将已声明未实例化的组件解析成为可以动态加载的compo