angular8 实现动态 加载组件

效果
源码

    业务场景: 动态数据源的tab切换框(tab的个数、名称、里面的内容是 动态的)。
    场景说明: ① 用户通过前台交互, 增加/删除某一类型的tab标签页, 
                         ② 将tab标签页的变化存储到后台 
                         ③ 从后台拿到新的tab标签页数据以后,渲染为 tab切换框。(这里只讨论③的实现)
   注意:
                ①   实现动态加载组件,最重要的3个部分:viewchild,viewContainerRef , componentFactoryResolver
                ②   angular8 中viewchild 需要2个参数,一个是模板变量的名称,另一个一般默认是{  static:false }  

  代码部分:
        目录结构(因为是个demo,所以结构比较简单,dynamic-tab-set组件就是动态加载组件的 tab切换框组件。dy1和dy2组件没什么东西,就是2个简单的初始化组件)

          angular8 实现动态 加载组件_第1张图片

         dynamic-tab-set.component.ts (为了方便演示,数据源就是假设的数据源 。dy1/2 既是需要加载的组件名,又是tab按键名,即tab的个数,名称,加载的内容是动态的,由后台数据源控制。)

//ViewChild 属性装饰器, 通过组件的模板变量,来获取组件元素。(可用作父子间组件通信的方式)
//ViewContainerRef 视图容器,在里面可以增,删组件
//ComponentFactoryResolver 动态加载组件的服务  
import { Component, OnInit, ViewContainerRef, ViewChild, ComponentFactoryResolver } from '@angular/core';

import { dynamicComponent } from '../dynamiModule';


@Component({
  selector: 'app-dynamic-tab-set',
  templateUrl: './dynamic-tab-set.component.html',
  styleUrls: ['./dynamic-tab-set.component.scss']
})
export class DynamicTabSetComponent implements OnInit {
  @ViewChild('componentContainer', { static: false, read: ViewContainerRef }) componentContainer: ViewContainerRef;

  //假设这是从后台拿取的数据。
  tabsData = [{
    name: 'dy1'
  }, {
    name: 'dy2'
  }]

  constructor(private cfr: ComponentFactoryResolver) { }

  ngOnInit() {
  }

  getDynamicComponents(name) {
    this.componentContainer.clear();
    let component = this.cfr.resolveComponentFactory(dynamicComponent[name]);
    this.componentContainer.createComponent(component);
  }

}

 

dynamic-tab-set.component.html 


  
  
    
  
  
  

dynamiModule.ts (由于 动态的组件,① 需要在当前module下 declarations数组中声明,②需要在当前module下 entryComponents数组中声明 ③ 需要在tab切换框页面 导入。 所以需要多次多个地方重复写import,太麻烦了)(参考文章)

import { Dy1Component } from './dy1/dy1.component';
import { Dy2Component } from './dy2/dy2.component';

const dynamicComponent = {
    'dy1': Dy1Component,
    'dy2': Dy2Component
}

const importComponents = [Dy1Component, Dy2Component];

export { dynamicComponent, importComponents }

app.component.html

 

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

import { DynamicTabSetComponent } from './dynamic-tab-set/dynamic-tab-set.component';
import { importComponents } from './dynamiModule';


@NgModule({
  declarations: [
    AppComponent,
    DynamicTabSetComponent,
    [...importComponents]
  ],
  entryComponents: [
    [...importComponents],
  ],
  imports: [
    BrowserModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

  参考文章1    参考文章2

你可能感兴趣的:(angular)