繁体   English   中英

Angular2 - 从模块动态加载组件

[英]Angular2 - Dynamically load component from module

在我的角度应用程序中,我有以下内容:

export class MyComponent {
    subcompPath = "path-to-subcomp#SubcompClassName";
    @ViewChild("placeholder", { read: ViewComponentRef }) placeholderRef: ViewComponentRef;

/* Constructor where Compiler, ComponentFactoryResolver are injected */

    loadSubcomponent() {
        let [path, componentName] = this.subcompPath.split("#");
        (<any>window).System.import(path)
            .then((module: any) => module[componentName])
            .then((type: any) => {
                return this._compiler.compileComponentAsync(type)
            })
            .then((factory: any) => {
                let componentRef = this.placeholderRef.createComponent(factory, 0);
            });
    }
}

我的子组件声明了提供者和东西,指令和管道。

而现在RC6又打破了一切。 组件不能声明指令和管道,但它们必须位于声明组件的模块中。 所以我必须加载SystemJS而不是组件本身而是模块。 好的,然后我应该使用

return this._compiler.compileModuleAndAllComponentsAsync(type)

很好,但是如何获得该特定组件的工厂参考? 那个工厂就是我所需要的,placeholderRef想要它的createComponent方法,对吧?

我试图从github挖掘angular2源代码,但是它非常庞大,我应该尝试使用VS Code或者其他东西,使用intellisense,但我很懒...我应该从文档中读取这些内容,这是相当乏味的angular.io这个特定的参数,它是没有路由器的组件和模块的延迟加载。

感谢任何帮助,我认为解决方案很容易应用,但没有官方文档很难找到。

更新:

如果你想将它与编译一起使用,你应该手动提供编译器

export function createJitCompiler () {
   return new JitCompilerFactory([{useDebug: false, useJit: true}]).createCompiler();
}
...
providers: [
  { provide: Compiler, useFactory: createJitCompiler}
],

旧版本

它可能会帮助你:

this.compiler.compileModuleAndAllComponentsAsync(DynamicModule)
      .then(({moduleFactory, componentFactories}) => {
        const compFactory = componentFactories
           .find(x => x.componentType === DynamicComponent);
        const cmpRef = this.placeholderRef.createComponent(compFactory, 0);

也可以看看

根据yurzui的回答,我来看下面的代码:

export class MyComponent {
    subcompPath = "path-to-subcompMODULE#SubcompClassName";
    @ViewChild("placeholder", { read: ViewComponentRef }) placeholderRef: ViewComponentRef;

    /* Constructor where Compiler, ComponentFactoryResolver are injected */

    loadSubcomponent() {
        let [modulePath, componentName] = this.subcompPath.split("#");
        (<any>window).System.import(modulePath)
            .then((module: any) => module["default"])  // Or pass the module class name too
            .then((type: any) => {
                return this._compiler.compileModuleAndAllComponentsAsync(type)
            })
            .then((moduleWithFactories: ModuleWithComponentFactories<any>) => {
                const factory = moduleWithFactories.componentFactories.find(x => x.componentType.name === componentName); // Crucial: componentType.name, not componentType!!
                let componentRef = this.placeholderRef.createComponent(factory, 0);
            });
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM