如何从已导入的模块创建组件?

时间:2016-11-17 15:24:28

标签: angular

我有一个模态服务,负责打开一个签名为create<T>(component: Type<T>, params?: Object, module: Type<{}> = AppModule): Observable<ComponentRef<T>>的模态对话框。模态服务的意思是问题是,当我导入已经导入的模块时,我收到错误Unexpected value 'undefined' declared by the module 'MyModule'。研究表明,在尝试两次导入时,这是一个常见问题。

ModalService -

import { Injectable, ComponentRef, ComponentFactoryResolver, ViewContainerRef, ReflectiveInjector, Injector, Compiler, Type } from '@angular/core';
import { Observable, ReplaySubject } from 'rxjs';
import { AppModule } from '../../app.module';

@Injectable()
export class ModalService {
    vcRef: ViewContainerRef;

    constructor(private componentFactoryResolver: ComponentFactoryResolver,
               private compiler: Compiler,
               private injector: Injector) {
    }

    registerViewContainerRef(vcRef: ViewContainerRef): void {
        this.vcRef = vcRef;
    }

    create<T>(component: Type<T>, params?: Object, module: Type<{}> = AppModule): Observable<ComponentRef<T>> {
        let componentRef$ = new ReplaySubject();

        this.compiler.compileModuleAndAllComponentsAsync(module)
            .then(factory => {
                let componentFactory = factory.componentFactories
                    .filter(item => item.componentType === component)[0];
                const childInjector = ReflectiveInjector.resolveAndCreate([], this.injector)
                let componentRef = this.vcRef.createComponent(componentFactory, 0, childInjector);

                Object.assign(componentRef.instance, params);

                componentRef$.next(componentRef);
                componentRef$.complete();
            });

        return <Observable<ComponentRef<T>>> componentRef$.asObservable();
    }
}
尝试使用属于FooComponent的组件MyModule打开模式对话框时的

用法代码段。

import { MyModule } '../my.module';
this.modalService.create(FooComponent, {}, MyModule)

根据文档,如果组件被延迟加载,则在创建组件时需要该模块。

我的问题是,如何创建属于已加载或未加载的任何模块的组件。

编辑!如果我正在动态创建的组件没有任何依赖关系,这种情况很有效,这种情况不太可能经常发生。

请参阅Plunker here。我遇到问题的地方是文件app/core/modal/modal.service.tsapp/crisis-center/crisis-list.component.ts(第54行 - 模式应该打开的地方)。显示的错误是Uncaught (in promise): Error: No provider for MyService!。不知道为什么,因为我从MyService被定义为提供者的模块创建我的组件。

是否有更好的方法来实现这一目标?

TL; DR目标是创建一个服务(在我的情况下为ModalService),无论它属于哪个模块,都可以创建任何组件。显然,它需要支持DI。

1 个答案:

答案 0 :(得分:0)

每次出现此错误时,重新启动CLI都会解决问题。在深入研究我的代码之前先尝试一下是件容易的事。