Angular学习笔记之-5.动态组件

动态组件加载器 (与vue的动态组件的应用场景类似)

译注:本页讲的是一个用于显示广告的范例,而部分广告拦截器插件,比如 Chrome 的 AdGuard,可能会破坏其工作逻辑,因此,请在本页关闭那些插件。

我的理解: 这个demo将指令绑定在,通过指令的viewContainerRef能够获取宿主元素,再通过ComponentFactoryResolver 来为每个具体的组件解析出一个 ComponentFactory。 然后 ComponentFactory 会为每一个组件创建一个实例。最后通过取宿主元素替换其中的内容或者说引用不同的组件

这个demo我是写在components模块里面,也将当前模块的index.module.ts代码粘贴出来
相关代码


        /* dynamic-source.service.ts 获取数据的service*/

        import { Injectable } from '@angular/core';

        import { DynamicComponentOneComponent } from './component-1';
        import { DynamicComponentTwoComponent } from './component-2';
        import { DynamicComponentThreeComponent } from './component-3';

        class DynamicComponent {
        components: any;
        data: any;
        constructor(components: any, data: any) {
            this.components = components;
            this.data = data;
        }
        }

        @Injectable()
        export class DynamicSourceService {
        getComponents() {
            return [
            new DynamicComponent(DynamicComponentOneComponent, {
                name: 'app-dynamic-component-1',
                age: 'Brave as they come',
            }),

            new DynamicComponent(DynamicComponentTwoComponent, {
                name: 'app-dynamic-component-2',
                age: 'Brave as they come',
            }),

            new DynamicComponent(DynamicComponentThreeComponent, {
                name: 'app-dynamic-component-3',
                age: 'Brave as they come',
            }),
            ];
            }
        }


        
        /* 
            dynamic.directive.ts 绑定到 <ng-template></ng-template>
            要在当前模块中声明该指令 
            @NgModule({
                declarations: [
                    DynamicComponent,
                    DynamicDirective,
                ],
                
            })
        */
        import { Directive, ViewContainerRef } from '@angular/core';

        @Directive({
        selector: '[adHost]',
        })
        export class DynamicDirective {
        constructor(public viewContainerRef: ViewContainerRef) {}
        }





        /* dynamic-component.ts 看到的界面*/
        import {
        Component,
        ComponentFactoryResolver,
        OnInit,
        AfterViewInit,
        ViewChild,
        } from '@angular/core';
        import { DynamicSourceService } from './dynamic-source.service';
        import { DynamicDirective } from './dynamic.directive';

        @Component({
        selector: 'dynamic-component',
        template: `
            <div class="dynamic-component">
            <h1 #adHost>app-dynamic-component</h1>
            <ng-template adHost></ng-template>
            <button (click)="loadingComponent(0)">app-dynamic-component-1</button>
            <button (click)="loadingComponent(1)">app-dynamic-component-2</button>
            <button (click)="loadingComponent(2)">app-dynamic-component-3</button>

            </div>
        `,
        providers: [DynamicSourceService],
        })
        export class DynamicComponent implements AfterViewInit {
        components: any[] = [];
        @ViewChild(DynamicDirective) adHost!: DynamicDirective;

        constructor(
            private dynamicSourceService: DynamicSourceService,
            private componentFactoryResolver: ComponentFactoryResolver
        ) {}

        ngAfterViewInit() {
            this.components = this.dynamicSourceService.getComponents();
            this.loadingComponent(0);
            // this returns null
        }

        loadingComponent(index:number) {
            const component = this.components[index];

            const ComponentFactory = this.componentFactoryResolver.resolveComponentFactory(
            component.components
            );

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

            const newComponent = viewContainerRef.createComponent<any>(
            ComponentFactory
            );
            setTimeout(() => {
            newComponent.instance.data = component.data;
            }, 0);
        }
        }


        /* 
            当前模块的modlue index.module.ts
            引入指令 组件 等
            
        */

        import { NgModule } from '@angular/core';
        import { CommonModule } from '@angular/common';
        import { FormsModule } from '@angular/forms';
        import { RouterModule } from '@angular/router';


        // 组件导入
        import { AppComponentsComponent } from './index.component';

        import { SpecialSelectorsParentComponent } from './components-css/special-selectors-host'
        import { SpecialSelectorsChilrenComponent } from './components-css/special-selectors-host'

        import { SpecialSelectorsHostContextParentComponent } from './components-css/special-selectors-host-context'
        import { SpecialSelectorsHostContextChilrenComponent } from './components-css/special-selectors-host-context'

        import { SpecialSelectorsDeepParentComponent } from './components-css/special-selectors-deep'
        import { SpecialSelectorsDeepChilrenComponent } from './components-css/special-selectors-deep'

        import {DynamicComponent} from './component-dynamic/dynamic-component'
        import {DynamicDirective } from '../components/component-dynamic/dynamic.directive'
        import {DynamicComponentOneComponent} from './component-dynamic/component-1'
        import {DynamicComponentTwoComponent} from './component-dynamic/component-2'
        import {DynamicComponentThreeComponent} from './component-dynamic/component-3'


        import {PopupComponent} from './components-angular-element/popup.component'
        import {AngularElementComponent} from './components-angular-element/angular-element.component'


        // 路由导入
        import { ComponentsRoutingModule } from './index-routing.module';

        @NgModule({
        declarations: [
            AppComponentsComponent,
            SpecialSelectorsParentComponent,
            SpecialSelectorsChilrenComponent,
            SpecialSelectorsHostContextParentComponent,
            SpecialSelectorsHostContextChilrenComponent,
            SpecialSelectorsDeepParentComponent,
            SpecialSelectorsDeepChilrenComponent,
            DynamicComponent,
            DynamicDirective,
            DynamicComponentOneComponent,
            DynamicComponentTwoComponent,
            DynamicComponentThreeComponent,
            PopupComponent,
            AngularElementComponent
        

        ],
        imports: [
            CommonModule,
            FormsModule,
            RouterModule,
            ComponentsRoutingModule,
        ],
        })
        export class AppComponentsModule { }
       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值