2016-09-02 9 views
7

in meinem Winkel app habe ich folgendes:Angular2 - Dynamisch Lastkomponente von Modul

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

Meine Subkomponente erklärt Anbieter und Sachen, Richtlinien und Rohre.

Und jetzt RC6 ist wieder alles zu brechen. Komponenten können keine Anweisungen und Pipes deklarieren, aber sie müssen sich in dem Modul befinden, in dem die Komponente deklariert ist. Also muss ich mit SystemJS nicht die Komponente selbst sondern das Modul laden. Ok, und dann soll ich

return this._compiler.compileModuleAndAllComponentsAsync(type) 

Gut, aber wie bekomme ich einen Verweis auf das Werk dieser spezifischen Komponente? Diese Fabrik ist alles was ich brauche, der PlatzhalterRef will es in seiner createComponent Methode, richtig?

Ich habe versucht, in den angular2 Quellcode von Github zu graben, aber es ist ziemlich groß, sollte ich von VS Code oder etwas mit Intellisense versuchen, aber ich bin faul ... und ich sollte dieses Zeug aus Dokumentation lesen, die ist in large.io ziemlich glanzlos für dieses spezielle Argument, welches das faule Laden von Komponenten und Modulen OHNE den Router ist.

Jede Hilfe ist willkommen, ich denke, die Lösung ist einfach anzuwenden, aber schwer zu finden ohne offizielle Dokumentation.

Antwort

8

Basierend auf yurzui Antwort Ich bin gekommen, um den folgenden Code:

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

entwickelt wurde Danke für thi!Können Sie ein Beispiel für * path-to-subcompMODULE # SubcompClassName * geben, während ich versuche, Module von einem momentan funktionierenden NPM-Modul zu laden: - http://stackoverflow.com/questions/39898417/angular- 2-Lazy-Loading-ein-ngmodul-in-a-npm-Modul-mit-Winkel-Router –

8

Update:

Wenn Sie es zusammen mit aot Kompilierung verwenden möchten, sollten Sie manuell Compiler wie

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

Example

Alte Version bereitstellen

Es könnte Ihnen helfen:

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

Siehe auch

+0

Thx @yurzui für den Zeiger, aber die Lösung für mein Problem ist eigentlich: 'const compFactory = moduleWithComponentFactory.componentFactories .find (x = > x.componentType.name === Komponentenname); ' Weil ich die Komponente dynamisch nach String suchen möchte, da ich während der Entwicklung den Typ nicht kenne, und ich nicht dynamisch einen Typ erstelle ... I kenne den Typnamen, da der Typ bereits irgendwo in einem Plugin zur Anwendung – Etchelon

Verwandte Themen