您的当前位置:首页正文

【Angular】angular2中动态组件加载

2024-11-11 来源:个人技术集锦



场景:

一天,蔬菜罐头公司要招聘一位萝卜去做萝卜干,因为上个萝卜被榨干了。于是在各大招聘网站上发布招聘信息。
岗位:蔬菜罐头加工人员
需要人数: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】

Top