如何通过打字稿代码动态注入 Angular2 子组件?

2024-01-08

上下文 - 我正在尝试创建一个可以包含多个组件的自定义下拉列表。我可以通过以下方式完成此任务<ng-content>标签,但我的团队顽固地坚持认为他们不喜欢这样。他们希望能够几乎完全通过打字稿代码实例化这个下拉列表。

我认为我可以通过 DynamicComponentLoader 来完成此任务,但不幸的是,我发现的所有优秀教程都使用了 loadIntoLocation() 函数,但该函数现在已经消失了。因此,我尝试使用 loadAsRoot() 函数,但它不起作用。

这就是我想做的:

Main.ts:

import { Component } from '@angular/core';
import { MyDropdown } from './MyDropdown';

@Component({
    selector: 'my-app',
    template: `
        <my-dropdown [contentModels]="dropdownContentModels"></my-dropdown>
    `
})
export class Main {
    dropdownContentModels: any[];
    constructor() {
        var someComponentModel = {selector: 'some-component', text: 'some'};
        var otherComponentModel = {selector: 'other-component', text: 'other'};
        this.dropdownContentModels = [someComponentModel, otherComponentModel];
    }
}

MyDropdown.ts:

import { Component } from '@angular/core';
import { InjectComponent } from './InjectComponent';

@Component({
    selector: 'my-dropdown',
    inputs: ['contentModels'],
    directives: [InjectComponent],
    template: `
        <div class="btn-group" dropdown>
            <button type="button" dropdownToggle>My Dropdown</button>
            <div class="dropdown-menu" role="menu">
                <inject-component *ngFor="let item of contentModels" [model]="item"></inject-component>
            </div>
        </div>
    `
})
export class MyDropdown {
    contentModels: any[];
}

注入组件.ts:

import { Component, DynamicComponentLoader, Injector } from '@angular/core';

@Component({
    selector: 'inject-component',
    inputs: ['model'],
    template: `
        <div #toreplace></div>
    `,
    providers: [DynamicComponentLoader, Injector]
})
export class InjectComponent {
    model: any;
    constructor(private dcl: DynamicComponentLoader, private injector: Injector) {}
    ngOnInit() {
        this.dcl.loadAsRoot(this.createWrapper(), '#toreplace', this.injector);
    }
    createWrapper(): any {
        var model = this.model;
        @Component({
            selector: model.selector + '-wrapper',
            template: '<' + model.selector + ' [model]="model"></' + model.selector + '>'
        })
        class Wrapper {
            model: any = model;
        }

        return Wrapper;
    }
}

但我收到运行时异常“异常:错误:未捕获(承诺中):只能添加到 TokenMap!令牌:注入器”

更新! (感谢 echonax):

注入组件.ts:

import { Component, ComponentResolver, ViewChild, ViewContainerRef, 
    ComponentFactory, ComponentRef } from '@angular/core';

@Component({
    selector: 'inject-component',
    inputs: ['model'],
    template: `
        <div #toreplace></div>
    `
})
export class InjectComponent {
    model: any;
    @ViewChild('toreplace', {read: ViewContainerRef}) toreplace;
    componentRef: ComponentRef<any>;

    constructor(private resolver: ComponentResolver) {}

    ngOnInit() {
        this.resolver.resolveComponent(this.createWrapper()).then((factory:ComponentFactory<any>) => {
            this.componentRef = this.toreplace.createComponent(factory);
        });
    }
    createWrapper(): any {
        var model = this.model;
        @Component({
            selector: model.selector + '-wrapper',
            directives: [ model.directives ],
            template: '<' + model.selector + ' [model]="model"></' + model.selector + '>'
        })
        class Wrapper {
            model: any = model;
        }

        return Wrapper;
    }
}

您可以使用新的.createComponent()功能。

import {ComponentRef, Injectable, Component, Injector, ViewContainerRef, ViewChild,ComponentResolver, DynamicComponentLoader} from '@angular/core';

export class InjectComponent {
    @ViewChild('toreplace', {read: ViewContainerRef}) toreplace;   


    constructor(private dcl: DynamicComponentLoader, injector: Injector,private resolver: ComponentResolver) {}

...

    this.resolver.resolveComponent((this.createWrapper()).then((factory:ComponentFactory<any>) => {
          this.cmpRef = this.theBody.createComponent(factory)
        });

并删除providers: [DynamicComponentLoader, Injector]

下面是一个使用 DynamicComponentLoader 的示例 plunker(在 app.component.ts 中):https://plnkr.co/edit/azoGdAUvDvCwJ3RsPXD6?p=preview https://plnkr.co/edit/azoGdAUvDvCwJ3RsPXD6?p=preview

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何通过打字稿代码动态注入 Angular2 子组件? 的相关文章

随机推荐