博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Angular 2.x+ 如何动态装载组件
阅读量:7043 次
发布时间:2019-06-28

本文共 2673 字,大约阅读时间需要 8 分钟。

Angular 2.x+ 如何动态装载组件

在 Angular 1.x 中我们可以使用
$compile 方法编译模板达到动态加载组件的目的,然而在 ng2 中则没有那么简单,下面的例子即为动态加载广告组件的过程。

首先,在添加组件前,我们需要定义一个锚点用于标识组件插入的位置,广告 banner 组件使用辅助指令
AdDirective 来标识模板中的有效插入位置。
// src/app/ad.directive.tsimport { Directive, ViewContainerRef } from '@angular/core';@Directive({  selector: '[ad-host]',})export class AdDirective {  constructor(public viewContainerRef: ViewContainerRef) { }}
AdDirective 通过注入
ViewContainerRef 来访问作为被插入组件宿主的节点视图容器。
class ViewContainerRef {   createComponent(componentFactory: ComponentFactory
, index?: number, injector?: Injector, projectableNodes?: any[][]) : ComponentRef
{ }}
  1. Component 所对应的 ComponentFactory 即是编译后的 Component 版本,所有与 Angular 运行时的实际交互都是通过 ComponentFactory 进行的
  2. 如果在 ViewContainerRef 中创建多个 Component/Template 那么 index 表示当前动态组件插入的位置
  3. 默认 Injector 是继承的,如果需要提供额外的 Provider,则需要使用 Injector 参数声明注入器(IoC 容器)
  4. projectableNodes 参数表示组件的 Transclude

ng-template 就是应用 AdDirective 组件的地方,用来告诉 Angular 动态组件加载到哪里。

// src/app/ad-banner.component.ts (template)template: `            

Advertisements

`
ng-template 是创建动态组件较好的选择,因为它不会渲染多余的输出。

AdBannerComponent 使用 AdItem 对象的数组作为输入属性,并通过 getAds 方法周期性地遍历 AdItem 对象数组,每隔 3s 调用 loadComponent 方法动态加载组件。

export class AdBannerComponent implements AfterViewInit, OnDestroy {  @Input() ads: AdItem[];  currentAddIndex: number = -1;  @ViewChild(AdDirective) adHost: AdDirective;  subscription: any;  interval: any;  constructor(private componentFactoryResolver: ComponentFactoryResolver) { }  ngAfterViewInit() {    this.loadComponent();    this.getAds();  }  ngOnDestroy() {    clearInterval(this.interval);  }  loadComponent() { ... }  getAds() {    this.interval = setInterval(() => {      this.loadComponent();    }, 3000);  }}
loadComponent 选择某个广告对象后,使用
ComponentFactoryResolver API 为每个相应的组件解析出一个
ComponentFactory 工厂类,用于创建组件的实例。
let adItem = this.ads[this.currentAddIndex];let componentFactory = this.componentFactoryResolver.resolveComponentFactory(adItem.component);
这里需要注意的是,
ViewContainerRef 只能通过在构造函数中直接声明来注入,因为
ViewContainerRef 的注入并不通过注入器,而是由编译器直接注入的,所以无法通过 Service 注入。
let viewContainerRef = this.adHost.viewContainerRef;viewContainerRef.clear();
我们可以调用
viewContainerRef
createComponent 方法实例化组件,该方法返回被加载的动态组件的引用,我们可以通过该引用修改组件的属性或者调用其方法。
let componentRef = viewContainerRef.createComponent(componentFactory);(
componentRef.instance).data = adItem.data;
同时这里存在一个容易误解的地方就是:创建动态组件必须通过
ViewContainerRef,实际上并不是,
ComponentFactory 本身就具有实例化组件的能力。
class ComponentFactory {  create(injector: Injector, projectableNodes?: any[][], rootSelectorOrNode?: string|any) : ComponentRef
{ }}

转载地址:http://iahal.baihongyu.com/

你可能感兴趣的文章
国际编程教育权威科学家菲利普.米勒教授来访 SegmentFault 总部
查看>>
API 标准化成为技术团队面临的最大挑战
查看>>
CSS 小三角
查看>>
Ruby on Rails 曝路径穿越与任意文件读取漏洞
查看>>
分享一个基于 Node.js 的 Web 开发框架 - Nokitjs
查看>>
mysql 简单全量备份和快速恢复
查看>>
全面解密QQ红包技术方案:架构、技术实现、移动端优化、创新玩法等 ...
查看>>
Python进阶:设计模式之迭代器模式
查看>>
Java是如何实现平台无关性的
查看>>
线上马戏团对接协议部分介绍
查看>>
一文纵览自然语言生成的发展
查看>>
常见seo骗局
查看>>
RNA药物研发初创公司Panorama Medicine完成370万美元种子轮融资 ...
查看>>
hanlp提取文本关键词的使用方法记录
查看>>
SpringBoot - 日志配置
查看>>
Python零基础学习笔记(十四)—— while语句
查看>>
swap释放过程浅析
查看>>
linux gzip
查看>>
Python知识点:lambda, map, filter
查看>>
zabbix snmp模板通用
查看>>