2016-09-02 14 views
7

w moim kątowej aplikacji mam następujące:Angular2 - Dynamiczne obciążenie ze składnikiem modułu

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); 
      }); 
    } 
} 

Moja Komponent deklaruje dostawców i rzeczy, dyrektyw i rur.

A teraz RC6 ma wszystko jeszcze raz złamać. Komponenty nie mogą deklarować dyrektyw i potoków, ale muszą znajdować się w module, w którym komponent jest zadeklarowany. Więc muszę załadować z SystemJS nie sam komponent, ale moduł. OK, a następnie należy użyć

return this._compiler.compileModuleAndAllComponentsAsync(type) 

dobrze, ale w jaki sposób uzyskać odniesienie do fabryki tego konkretnego komponentu? Ta fabryka jest wszystkim, czego potrzebuję, placeholderRef chce tego w swojej metodzie createComponent, prawda?

Próbowałem zagłębić się w kod źródłowy angular2 z github, ale jest dość rozległy, powinienem spróbować z VS Code lub czegoś, z intellisense, ale jestem leniwy ... i powinienem przeczytać to z dokumentacji, która jest dość słabe w angular.io dla tego konkretnego argumentu, który jest leniwym ładowaniem komponentów i modułów BEZ routera.

Każda pomoc jest doceniana, myślę, że rozwiązanie jest proste w zastosowaniu, ale trudne do znalezienia bez oficjalnej dokumentacji.

Odpowiedz

8

Na podstawie odpowiedzi yurzui za doszedłem do następującego kodu:

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); 
      }); 
    } 
} 
+0

Dzięki za thi!Czy możesz podać przykład * path-to-subcompMODULE # SubcompClassName *, gdy próbuję uzyskać leniwy ładowanie modułów z modułu NPM działającego w tej chwili: - http://stackoverflow.com/questions/39898417/angular- 2-leniwy ładowanie-a-ngmoduł-w-a-npm-moduł-z-kątowym-routerem –

8

Aktualizacja:

Jeśli chcesz go używać razem z AOT kompilacji należy ręcznie zapewnić Compiler jak

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

Example

starą wersję

To może pomóc:

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

Zobacz także

+0

Thx @yurzui dla wskaźnika, ale rozwiązanie mojego problemu jest rzeczywiście: 'const compFactory = moduleWithComponentFactory.componentFactories .find (x = > x.componentType.name === nazwaKomponentu); ' Ponieważ chcę znaleźć komponent dynamicznie według ciągu znaków, ponieważ nie wiem podczas tworzenia tego typu i nie tworzę dynamicznie typu ... I znać nazwę typu, ponieważ typ został już opracowany gdzieś w wtyczce do aplikacji – Etchelon

Powiązane problemy