美文网首页
Angular 动态组件加载

Angular 动态组件加载

作者: Messix_1102 | 来源:发表于2022-12-13 09:10 被阅读0次

    1.首先定义一个辅助指令

    辅助指令用来标记 动态组件 的插入点

    // ad.directive.ts
    
    import { Directive, ViewContainerRef } from '@angular/core';
    
    @Directive({
      selector: '[adHost]',
    })
    export class AdDirective {
      constructor(public viewContainerRef: ViewContainerRef) { }
    }
    

    2.定义需要动态插入的组件

    // ad.component.ts 组件统一接口
    export interface AdComponent {
        data: any;
    }
    
    // hero-job-ad.component.ts 动态组件
    import { Component, Input } from '@angular/core';
    import { AdComponent } from './ad.component';
    
    @Component({
      template: `
        <div class="job-ad">
          <h4>{{data.headline}}</h4>
          {{data.body}}
        </div>
      `
    })
    export class HeroJobAdComponent implements AdComponent {
      @Input() data: any;
    }
    
    // hero-profile.component.ts 动态组件
    import { Component, Input } from '@angular/core';
    import { AdComponent } from './ad.component';
    
    @Component({
      template: `
        <div class="hero-profile">
          <h3>Featured Hero Profile</h3>
          <h4>{{data.name}}</h4>
    
          <p>{{data.bio}}</p>
    
          <strong>Hire this hero today!</strong>
        </div>
      `
    })
    export class HeroProfileComponent implements AdComponent {
      @Input() data: any;
    }
    

    3.定义Service获取所有的动态组件

    // ad.service.ts
    import { Injectable } from '@angular/core';
    import { HeroJobAdComponent } from './hero-job-ad.component';
    import { HeroProfileComponent } from './hero-profile.component';
    import { AdItem } from './ad-item';
    
    @Injectable()
    export class AdService {
      getAds() {
        return [
          new AdItem(
            HeroProfileComponent,
            { name: 'Bombasto', bio: 'Brave as they come' }
          ),
          new AdItem(
            HeroProfileComponent,
            { name: 'Dr IQ', bio: 'Smart as they come' }
          ),
          new AdItem(
            HeroJobAdComponent,
            { headline: 'Hiring for several positions', body: 'Submit your resume today!' }
          ),
          new AdItem(
            HeroJobAdComponent,
            { headline: 'Openings in all departments', body: 'Apply today' }
          )
        ];
      }
    }
    
    // ad-item.ts 动态组件传参对象
    import { Type } from '@angular/core';
    
    export class AdItem {
      constructor(public component: Type<any>, public data: any) {}
    }
    

    4.定义容器,动态展示

    //ad-banner.component.ts
    
    import { Component, ViewContainerRef, ComponentFactoryResolver, Input, OnDestroy, OnInit, ViewChild} from '@angular/core';
    
    import { AdItem } from './ad-item';
    import { AdService } from './ad.service';
    import { AdDirective } from './ad.directive';
    import { AdComponent } from './ad.component';
    
    @Component({
      selector: 'app-ad-banner',
      template: `
        <div class="ad-banner-example">
          <h3>Advertisements</h3>
          <ng-template [adHost]="adItem"></ng-template>
        </div>
      `
    })
    export class AdBannerComponent implements OnInit, OnDestroy {
      ads: AdItem[];
    
      currentAdIndex = -1;
    
      @ViewChild(AdDirective, {static: true}) adHost!: AdDirective;
      interval: any = 0;
    
      constructor(private componentFactoryResolver: ComponentFactoryResolver,
        private adService: AdService){
        this.ads = this.adService.getAds();
      }
      
      ngOnInit(): void {
        this.loadComponent();
        this.getAds();
      }
    
      ngOnDestroy() {
        clearInterval(this.interval);
      }
    
      loadComponent() {
        this.currentAdIndex = (this.currentAdIndex + 1) % this.ads.length;
        const adItem = this.ads[this.currentAdIndex];
    
        const viewContainerRef = this.adHost.viewContainerRef;
        viewContainerRef.clear();
    
        const componentFactory = this.componentFactoryResolver.resolveComponentFactory(adItem.component);
        const componentRef = viewContainerRef.createComponent<AdComponent>(componentFactory);
        componentRef.instance.data = adItem.data;
      }
    
      getAds() {
        this.interval = setInterval(() => {
          this.loadComponent();
        }, 3000);
      }
    }
    

    相关文章

      网友评论

          本文标题:Angular 动态组件加载

          本文链接:https://www.haomeiwen.com/subject/cxdcqdtx.html