Подтвердить что ты не робот

Angular2: динамическая загрузка модулей из заданной папки

app
 |-plugins
       |-plugin1
           |-config.json
           |-plugin1.module.ts
           |-plugin1.component.ts

       |-plugin2
           |-config.json
           |-plugin2.module.ts
           |-plugin2.component.ts

Как вы можете видеть выше, у меня есть папка "app/plugins" , которая содержит плагины. Каждый плагин будет содержать один файл "config.json", который расскажет о некоторой конфигурации, включая -

{
   path: "feature1",
   moduleFile: "feature1.module",
   moduleClassName: "Feature1Module"
}

Так что я хочу, перед загрузкой приложения он сканирует папку "приложение/плагины" и загружает все конфигурации плагинов и лениво регистрирует все маршруты модулей. Для примера выше маршрут будет

{
     path: "feature1",
     loadChildren: "app/plugins/plugin1/plugin1.module#Plugin1Module"
}

Таким образом, мы можем добавить новый плагин в папку плагина и обновить приложение, а наш недавно выпущенный плагин запущен и работает.

Кто-нибудь знает, как я могу это достичь?

ПРИМЕЧАНИЕ. Я нахожусь на angular2 последней (2.1.0)

4b9b3361

Ответ 1

Я ищу такое же поведение, как тот, который вы описываете, и я думаю, что нашел, как это сделать, благодаря этой проблеме github: ленивые компоненты загрузки без маршрута

Вот код, который я написал для этого: plunker here

  • Сначала: dynamic.module.ts, динамически загруженный модуль и его компонент

    import { Component, NgModule } from '@angular/core'
    
    @Component({
        selector: 'my-test',
        template: `<h1>html template of TestComponent from DynamicModule</h1>`
    })
    
    export class TestComponent { }
    
    @NgModule({
        declarations: [TestComponent],
        exports: [TestComponent]
    })
    
    export class DynamicModule { }
    
  • Во-вторых: вот компонент, который динамически загружает модуль, когда вы даете ему путь к модулю.

    import {
    Component, 
    ViewContainerRef,
    Compiler,
    ComponentFactory,
    ComponentFactoryResolver,
    ModuleWithComponentFactories,
    ComponentRef,
    ReflectiveInjector,
    SystemJsNgModuleLoader } from '@angular/core';
    
    class ModuleNode {
        modulePath: string;
        componentName: string;
    }
    
    @Component({
        moduleId: module.id,
        selector: 'widgetContainer',
        templateUrl: './widgetContainer.component.html'
    })
    
    export class WidgetContainerComponent {
        widgetConfig: string;
        module: ModuleNode;
        cmpRef: ComponentRef<any>;
    
    constructor(private widgetService: WidgetLoader,
        private viewref: ViewContainerRef,
        private resolver: ComponentFactoryResolver,
        private loader: SystemJsNgModuleLoader,
        private compiler: Compiler){}
    
    openWebApp(menu:any) {
        this.loader.load(menu.modulePath)  // load the module and its components
            .then((modFac) => {
                // the missing step, need to use Compiler to resolve the module embedded components
                this.compiler.compileModuleAndAllComponentsAsync<any>(modFac.moduleType)
    
                    .then((factory: ModuleWithComponentFactories<any>) => {
                        return factory.componentFactories.find(x => x.componentType.name === menu.componentName);
                    })
                    .then(cmpFactory => {
    
                        // need to instantiate the Module so we can use it as the provider for the new component
                        let modRef = modFac.create(this.viewref.parentInjector);
                        this.cmpRef = this.viewref.createComponent(cmpFactory, 0, modRef.injector);
                        // done, now Module and main Component are known to NG2
    
                    });
            });
    }
    
    ngOnDestroy() {
        if (this.cmpRef) {
            this.cmpRef.destroy();
        }
    }
    

    }

Что вы думаете об этом? Помогает ли это? Большое спасибо за ваши отзывы.