2017-02-27 127 views
2

所以我試圖創建一個模塊,它會動態加載一些組件並動態加載它們,但不會混淆AoT。這已經證明是一個挑戰,但除了一件事情之外,我會變得非常親密。如何檢索存儲在ComponentFactory中的所有組件?在不破壞AoT的情況下動態加載組件 - Angular2

在自我介紹app.module.ts我傳遞部件的陣列到forRoot()我的動態負載模塊的:

imports: [ 
    DynamicLoadModule.forRoot(dynamicComponents), 
] 

以我dynamic-load.module.ts我他們都添加到Angular2 ComponentFactory:

static forRoot(components: any[]) { 
     return { 
      ngModule: DynamicLoadModule, 
      providers: [{ 
       provide: ANALYZE_FOR_ENTRY_COMPONENTS, 
       useValue: components, 
       multi: true, 
      }, { 
       provide: DynamicLoadService, 
       useValue: new DynamicLoadService(components) 
      }] 
     }; 
    } 

現在問題在於DynamicLoadService,這與AoT混淆。我已經嘗試了記錄的導出功能的方式,但這並不能解決問題,因爲這樣我無法將components作爲參數傳遞給服務。因此,在the Angular documentation下面發現並沒有提供給我的問題的解決方案:

let heroServiceFactory = (logger: Logger, userService: UserService) => { 
    return new HeroService(logger, userService.user.isAuthorized); 
}; 

export let heroServiceProvider = 
    { provide: HeroService, 
    useFactory: heroServiceFactory, 
    deps: [Logger, UserService] 
    }; 

於是我試圖通過使用OpaqueToken,這是沒有幫助的也傳遞組件到我的dynamic-load.module,因爲我再有未編譯組件充其量,我的模塊失去了很多的靈活性。

所以我得出結論,如果我需要ComponentFactory中所有組件的數組,我只需要一種方法來檢索它們。
因此,我現在使用ComponentFactoryResolver來獲取一個基於我需要的名稱的模板,或者至少獲取工廠中所有組件的名稱。

if (selectedComponent !== '') { 
    if (typeof this.currentComponent !== 'undefined') { this.currentComponent.destroy(); } 

    const components = this.dynamicLoadService.getComponents(), // --> instead of getting a list of available components through this service which needs the factory that blocks AoT, I should just be able to retrieve all available components from the ComponentFactory 
      component: any = components.find((x) => x.name.toLowerCase().indexOf(selectedComponent) > -1), 
      compFactory = this.cfr.resolveComponentFactory(component); 

    this.currentComponent = this.vcr.createComponent(compFactory); 
    this.currentComponent.instance.data = this.componentData; 
} 

回答

2

編輯 所以第一個答案並沒有完全解決問題,但另一個樂於助人的人能夠幫助我通過Angular Github解決問題。

在結束我的代碼如下:

import { NgModule, ANALYZE_FOR_ENTRY_COMPONENTS, Inject } from '@angular/core'; 
import { DynamicLoadService } from './dynamic-load.service'; 

import { DynamicLoadComponent } from './dynamic-load.component'; 

export function DynamicLoadFactory(cmps) { 
    return new DynamicLoadService(cmps); 
} 

@NgModule({ 
    declarations: [ 
     DynamicLoadComponent 
    ], 
    exports: [ 
     DynamicLoadComponent 
    ] 
}) 
export class DynamicLoadModule { 
    static forRoot(components: any[]) { 
     return { 
      ngModule: DynamicLoadModule, 
      providers: [{ 
       provide: ANALYZE_FOR_ENTRY_COMPONENTS, 
       useValue: components, 
       multi: true 
      }, 
      { 
       provide: 'ENTRIES', 
       useValue: components 
      }, 
      { 
       provide: DynamicLoadService, 
       useFactory: DynamicLoadFactory, 
       deps: [[new Inject('ENTRIES')]] 
      }] 
     }; 
    } 
} 

正如向我指出ANALYZE_FOR_ENTRY_COMPONENTS不是依賴注入樹的一部分(尋源here)。所以上面的解決方法處理這個問題。


所以我的回答就是在Angular Github上非常有幫助的人。

有人提議,我認爲我應該只是

剛剛注入ANALYZE_FOR_ENTRY_COMPONENTSDynamicLoadService

現在看起來是這樣的:

export function DynamicLoadFactory(cmps) { 
    return new DynamicLoadService(cmps); 
} 

export class DynamicLoadModule { 
    static forRoot(components: any[]) { 
     return { 
      ngModule: DynamicLoadModule, 
      providers: [{ 
       provide: ANALYZE_FOR_ENTRY_COMPONENTS, 
       useValue: components, 
       multi: true, 
      }, { 
       provide: DynamicLoadService, 
       useFactory: DynamicLoadFactory, 
       deps: [new Inject(ANALYZE_FOR_ENTRY_COMPONENTS)] 
      }] 
     }; 
    } 
} 

source at Github

相關問題