2016-10-14 2 views
21
app 
|-plugins 
     |-plugin1 
      |-config.json 
      |-plugin1.module.ts 
      |-plugin1.component.ts 

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

Как вы можете видеть выше, у меня есть «приложение/плагины» папку, которая содержит плагины. Каждый модуль содержит один файл «config.json», который расскажет некоторые конфигурации, включая -Angular2: Загрузка модулей динамически из заданной папки

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

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

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

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

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

Примечание: Я на angular2 последней (2.1.0)

+0

Почему бы просто не использовать 'NgModule' для каждой функции? – Sasxa

+1

Я использую NgModule для каждой функции, но я хочу знать, как я могу прочитать все папки и прочитать конфигурацию, чтобы я мог лениво регистрировать эти модули. –

+0

Я думаю, вам придется написать сценарий nodejs и сгенерировать код вручную. Это не Угловая вещь ... – Sasxa

ответ

13

Я ищу такое же поведение, чем та, вы описываете, и я думаю, что я нашел, как это сделать, спасибо к этому GitHub вопрос: Lazy loading components without Route

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

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

    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's 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(); 
        } 
    } 
    

    }

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

+1

Работает ли это, если ваше приложение Angular развернуто с AOT? –

+5

@ DouaBeri: Нет. К несчастью, это не работает с AOT. Мы должны были отдать это из-за компиляции AOT. –

+0

Мне жаль, что я не задал этот вопрос и принял бы его как гениальный ответ, блестящий брат, js блестящий, расслоение благодарности –

Смежные вопросы