angular2中动态组件加载

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/my_study_everyday/article/details/84072519

参考:angular2(4) 中动态创建组件的两种方案
参考:DEVELOPING A TABS COMPONENT IN ANGULAR
参考:Create a dynamic tab component with Angular

解析:官网案例

组件的模板不会永远是固定的。应用可能会需要在运行期间加载一些新的组件。
这篇博客为你展示如何使用ComponentFactoryResolver来动态添加组件。

萝卜招聘

场景:

一天,蔬菜罐头公司要招聘一位萝卜去做萝卜干,因为上个萝卜被榨干了。于是在各大招聘网站上发布招聘信息。
岗位:蔬菜罐头加工人员
需要人数:1
岗位职责:选个秋高气爽好日子,把脆嫩汁液很充足的萝卜洗白白后,用不油腻的菜刀把萝卜干纵切成3厘米到5厘米之间的长条块,凉上一天。然后找一个适当容量的玻璃坛子,瓦坛子或是瓦缸也行,洗干净晾干。然后采用浸泡法去腌制脆口的萝卜干。

##1.首先找招聘网站把招聘信息发布出去(定义一个指令)

动态加载组件,就像蔬菜罐头公司的岗位等待萝卜入坑一样。萝卜怎么知道该公司有岗位呢?通过招聘网站(指令,就像锚点一样告诉萝卜我司有坑,来吧)。

//定义指令
import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[ad-host]',
})
export class AdDirective {
  constructor(public viewContainerRef: ViewContainerRef) { }
}

AdDirective注入了ViewContainerRef来获取对容器视图的访问权,这个容器就是那些动态加入的组件的宿主。可以在该容器上创建、插入、删除组件等等。
在@Directive装饰器中,要注意选择器的名称:ad-host,它就是我们将应用到(容器)元素上的指令

搞个岗位出来(不然萝卜来了没有坑,尬聊吗,弄个容器出来)

import { Component, Input, AfterViewInit, ViewChild, ComponentFactoryResolver, OnDestroy } from '@angular/core';

import { AdDirective } from './ad.directive';
import { AdItem }      from './ad-item';
import { AdComponent } from './ad.component';

@Component({
  selector: 'add-banner',
  template: `
              <div class="ad-banner">
                <h3>Advertisements</h3>
                <ng-template ad-host></ng-template>
              </div>
            `
})
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() {
    this.currentAddIndex = (this.currentAddIndex + 1) % this.ads.length;
    let adItem = this.ads[this.currentAddIndex];

    let componentFactory = this._componentFactoryResolver.resolveComponentFactory(adItem.component);

    let viewContainerRef = this.adHost.viewContainerRef;
    viewContainerRef.clear();

    let componentRef = viewContainerRef.createComponent(componentFactory);
    (<AdComponent>componentRef.instance).data = adItem.data;
  }

  getAds() {
    this.interval = setInterval(() => {
      this.loadComponent();
    }, 3000);
  }
}

这个岗位一看就不简单。要学习的东西很多。比如浸泡法。可以说是一个神坑,包罗万象。什么ngAfterViewInit,ViewChild,ComponentFactoryResolver,OnDestroy,<ng-template ad-host></ng-template>等等etc

  • ViewChild一个属性装饰器,用来从模板视图中获取对应的元素,可以通过模板变量获取,获取时可以通过 read 属性设置查询的条件,就是说可以把此视图转为不同的实例
  • ComponentFactoryResolver一个服务,动态加载组件的核心,这个服务可以将一个组件实例呈现到另一个组件视图上
  • <ng-template ad-host></ng-template>来自ad.directive.ts的选择器ad-host。把它应用到<ng-template>。 这下,Angular就知道该把组件动态加载到哪里了
  • ngAfterViewInit见生命周期钩子章节
  • OnDestroy见生命周期钩子章节

一个简单的思路便连贯了:特定区域就是一个视图容器,可以通过 ViewChild 来实现获取和查询,然后使用ComponentFactoryResolve将已声明未实例化的组件解析成为可以动态加载的 component,再将此component 呈现到此前的视图容器中

【微信公众号:qdgithub】

猜你喜欢

转载自blog.csdn.net/my_study_everyday/article/details/84072519