资讯专栏INFORMATION COLUMN

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

Yi_Zhi_Yu / 3629人阅读

摘要:如何动态装载组件在中我们可以使用方法编译模板达到动态加载组件的目的,然而在中则没有那么简单,下面的例子即为动态加载广告组件的过程。是创建动态组件较好的选择,因为它不会渲染多余的输出。

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

live demo

首先,在添加组件前,我们需要定义一个锚点用于标识组件插入的位置,广告 banner 组件使用辅助指令 AdDirective 来标识模板中的有效插入位置。
// src/app/ad.directive.ts
import { 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 { }
}

Component 所对应的 ComponentFactory 即是编译后的 Component 版本,所有与 Angular 运行时的实际交互都是通过 ComponentFactory 进行的

如果在 ViewContainerRef 中创建多个 Component/Template 那么 index 表示当前动态组件插入的位置

默认 Injector 是继承的,如果需要提供额外的 Provider,则需要使用 Injector 参数声明注入器(IoC 容器)

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();
我们可以调用 viewContainerRefcreateComponent 方法实例化组件,该方法返回被加载的动态组件的引用,我们可以通过该引用修改组件的属性或者调用其方法。
let componentRef = viewContainerRef.createComponent(componentFactory);
(componentRef.instance).data = adItem.data;
同时这里存在一个容易误解的地方就是:创建动态组件必须通过 ViewContainerRef,实际上并不是,ComponentFactory 本身就具有实例化组件的能力。
class ComponentFactory {
  create(injector: Injector, projectableNodes?: any[][], rootSelectorOrNode?: string|any) : ComponentRef { }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83130.html

相关文章

  • Angular 2.x 从0到1 (一)史上最简单的Angular2教程

    摘要:官方支持微软出品,是的超集,是的强类型版本作为首选编程语言,使得开发脚本语言的一些问题可以更早更方便的找到。第一个组件那么我们来为我们的增加一个吧,在命令行窗口输入。引导过程通过在中引导来启动应用。它们的核心就是。 第一节:Angular 2.0 从0到1 (一)第二节:Angular 2.0 从0到1 (二)第三节:Angular 2.0 从0到1 (三) 第一章:认识Angular...

    tuniutech 评论0 收藏0
  • 使用ng2-admin搭建成熟可靠的后台系统 -- ng2-admin(五)

    摘要:创建一个工具类,负责提供以及完成拼接参数的工作。根据我们的配置,来创建这个文件。因为是表单提交,所以我们新建一个服务,由它来完成表单提交的最后一步。 使用ng2-admin搭建成熟可靠的后台系统 -- ng2-admin(五) 完善动态表单组件 升级Angular 4.1 -> 4.3 添加 json-server 模拟数据 创建自己的 http 完成一次表单提交 升级Angu...

    MiracleWong 评论0 收藏0
  • angular - 收藏集 - 掘金

    摘要:如何在中使用动画前端掘金本文讲一下中动画应用的部分。与的快速入门指南推荐前端掘金是非常棒的框架,能够创建功能强大,动态功能的。自发布以来,已经广泛应用于开发中。 如何在 Angular 中使用动画 - 前端 - 掘金本文讲一下Angular中动画应用的部分。 首先,Angular本生不提供动画机制,需要在项目中加入Angular插件模块ngAnimate才能完成Angular的动画机制...

    AlexTuan 评论0 收藏0
  • 使用ng2-admin搭建成熟可靠的后台系统 -- ng2-admin(三)

    摘要:使用搭建成熟可靠的后台系统三完善动态表单添加样式。下一章会讲解,一个集成的服务,来完成我们的提交,在将来的篇章里会在我们的组件中加入使其变得更加灵活。 使用ng2-admin搭建成熟可靠的后台系统 -- ng2-admin(三) 完善动态表单 添加样式。 抽离组件。 添加组件样式 上一篇文章创建了两个,组件,现在使用bootstrap来给他们添加一些样式 首先需要一个公用的 s...

    张宪坤 评论0 收藏0
  • Angular 4 简单入门笔记

    摘要:首先,我们需要在入口页面的中配置根路径然后创建一个路由模块路由配置在主模块中导入配置好的路由模块而在页面中需要一个容器去承载上面代码中的定义了用户点击后的路由跳转,定义该路由激活时的样式类。 刚实习的时候用过AngularJS,那时候真的是连原生JavaScript都不会写,依样画葫芦做了几个管理后台。然后突然换项目了,AngularJS就不写了,感觉前前后后接触了一年多的Angula...

    whlong 评论0 收藏0

发表评论

0条评论

Yi_Zhi_Yu

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<