2016-08-18 11 views
1

私はAngular 2をRuntimeCompilerを使ってHTMLの断片を動的にコンパイルしようとしています。私はこのpostの解決策を見つけました(Angular 2.0 RC 5 related答え)、コンポーネントのデコレータでインラインテンプレートの代わりにtemplateUrlを使用するまで機能します。私はtemplateUrlを使用する場合角2 RuntimeCompiler:XHRの実装は提供されていません

@Component({ 
    selector: 'dynamic-detail', 
    providers: [DynamicTypeBuilder, DynamicTemplateBuilder], 
    templateUrl: 'app/dynamic/detail.view.html', 
}) 

、私は次のエラーを取得する:

Unhandled Promise rejection: EXCEPTION: Error in ./AppComponent class AppComponent - inline template:4:3 
ORIGINAL EXCEPTION: Error: No XHR implementation has been provided. Can't read the url "app/dynamic/detail.view.html" 
ORIGINAL STACKTRACE: 
Error: No XHR implementation has been provided. Can't read the url "app/dynamic/detail.view.html" 

動的コンパイル時の角度は、それがHTTP経由でのHTMLテンプレートを読み込むことができないので、それはXHR実装だ失うように見えます。 誰でも助けてもらえますか?

私の例はplunkerです。 バージョン3 - templateUrlの例(コンテンツは動的に読み込まれません) バージョン2 - インラインテンプレートの例(everythinkは正常に動作します)。

答えて

0

同様の「バグ」が角度の問題で育った: https://github.com/angular/angular/issues/11015

あなたは私のスニペットに従えば、あなたは唯一の「コンテナ」のためではなく、「ウィジェット」のtemplateUrlを使用することができます。

import { 
    Component, 
    ComponentFactoryResolver, 
    ViewContainerRef, 
    ViewChild, 
    OnInit, 
    Compiler 
} from '@angular/core'; 
import {RuntimeCompiler} from "@angular/compiler"; 
import {EmptyModule} from "./empty.module"; 

export class MyComponentLoader { 
    loadComponentConfig(url) { 
    return fetch(url) 
     .then(res => res.json()) 
     .then(componentList => Promise.all(
     componentList.map(config => this.loadComponent(config)) 
     ) 
    ); 
    } 

    loadComponent(configObject) { 
    return System.import(configObject.path) 
       .then(componentModule => 
        componentModule[configObject.component] 
       ) 
    } 
} 

@Component({ 
    moduleId: module.id, 
    selector: 'ng-smartdesk', 
    templateUrl: './smartdesk.component.html', 
    providers: [MyComponentLoader], 
}) 
export class SmartdeskComponent implements OnInit { 
    @ViewChild('widgets', {read: ViewContainerRef}) 
    container: ViewContainerRef; 

    constructor(private _loader: MyComponentLoader, 
       protected _compiler: RuntimeCompiler) { 
    } 

    ngOnInit() { 
    this._loader.loadComponentConfig('/app/config.json') 
     .then(components => { 
      if (components) { 
      Promise.all(components.map(test => this.loadComp(test, null))); 
      } 
     }, error => console.log(error)); 
    } 

    private loadComp(comp: Component, index: number) { 
    this._compiler 
     .compileComponentAsync(comp, EmptyModule) 
     .then(factory => { 
      this.container.createComponent(factory, index, this.container.injector) 
     }); 
    } 
} 

編集:解決済み! Tobias Boschの助けを借りて、解決策はコンパイラの新しいインスタンスを作成することです。これは私の最終的なコードです:

import { 
 
    Component, 
 
    ComponentFactoryResolver, 
 
    ViewContainerRef, 
 
    ViewChild, 
 
    OnInit, 
 
    Compiler, CompilerFactory 
 
} from '@angular/core'; 
 
import {RuntimeCompiler} from "@angular/compiler"; 
 
import {EmptyModule} from "./empty.module"; 
 
import {platformBrowserDynamic} from "@angular/platform-browser-dynamic"; 
 

 
export class MyComponentLoader { 
 
    loadComponentConfig(url) { 
 
    return fetch(url) 
 
     .then(res => res.json()) 
 
     .then(componentList => Promise.all(
 
     componentList.map(config => this.loadComponent(config)) 
 
     ) 
 
    ); 
 
    } 
 

 
    loadComponent(configObject) { 
 
    return System.import(configObject.path) 
 
       .then(componentModule => 
 
        componentModule[configObject.component] 
 
       ) 
 
    } 
 
} 
 

 
@Component({ 
 
    moduleId: module.id, 
 
    selector: 'ng-smartdesk', 
 
    templateUrl: './smartdesk.component.html', 
 
    providers: [MyComponentLoader], 
 
}) 
 
export class SmartdeskComponent implements OnInit { 
 
    @ViewChild('widgets', {read: ViewContainerRef}) 
 
    container: ViewContainerRef; 
 
    private _compiler; 
 

 
    constructor(private _loader: MyComponentLoader) { 
 
    const compilerFactory : CompilerFactory = platformBrowserDynamic().injector.get(CompilerFactory); 
 
    this._compiler = compilerFactory.createCompiler([]); 
 
    } 
 

 
    ngOnInit() { 
 
    this._loader.loadComponentConfig('/app/config.json') 
 
     .then(components => { 
 
      if (components) { 
 
      Promise.all(components.map(test => this.loadComp(test, null))); 
 
      } 
 
     }, error => console.log(error)); 
 
    } 
 

 
    private loadComp(comp: Component, index: number) { 
 
    this._compiler 
 
     .compileComponentAsync(comp, EmptyModule) 
 
     .then(factory => { 
 
      this.container.createComponent(factory, index, this.container.injector) 
 
     }); 
 
    } 
 
}

0

@ ComponentデコレータのmoduleIid:module.idを追加します。

詳細はarticleをご確認ください。

+0

、@sbeci、ありがとうございました。残念ながらあなたの解決策は動作しません - もしそれがmodule.idの問題であれば、私は404エラーになります - しかし、私のエラーはよりトリッキーです –

関連する問題