2017-08-04 3 views
3

角型アプリケーションに問題があります。角型アプリケーションに動的外部コンポーネントを読み込む方法

私は、(aot)でTypscriptビルドで書かれた角度のアプリケーションを持っていたいと思います。

目的は、いくつかのウィジェットを持つユーザーダッシュボードを表示することです。ウィジェットは角度成分です。

私のアプリにはウィジェットが組み込まれています。 しかし、ウィジェットは市場のようなもので拡張する必要があります。手動で作成することもできます。

市場では、ファイル(js/ts/bunlde .. ??)を特定のフォルダにダウンロードする必要があります。

私のアプリは新しいウィジェット(= ngコンポーネント)を読み込んでインスタンス化できるはずです。

マイフォルダ構造(生産)

|- index.html 
    |- main.f5b448e73f5a1f3f796e.bundle.js 
    |- main.f5b448e73f5a1f3f796e.bundle.js.map 
    |- .... (all other files generated) 
    |- externalWidgets 
     |- widgetA 
      |- widjetA.js 
      |- widjetA.js.map 
      |- assets 
       |- image.png 
     |- widgetB 
      |- widjetB.ts 
      |- widjetB.html 
      |- widjetB.css 

ユーザーページをロードするときに、データベースがwidgetAがあることを言います。 これは、ファイルを動的にロードし、含まれているコンポーネントをインスタンス化することを目的としています。

"require"と "System.import"を使用して多くのソリューションを試しましたが、ロードするパスが動的に生成されたときに両方が失敗します。

これは可能でしょうか? 自分のコード構造を変更できます。 (例えば、widgetBはまだ蒸散されていない、など...)

実際、私はAngular4/webpackアプリケーションで「プラグインシステム」を探しています。

答えて

4

私はまったく同じことをしています。

最初に理解しなければならないのは、Webpackはビルド時に不明なモジュールを動的にロードできないということです。これは、Webpackが依存関係ツリーを構築し、ビルド時にモジュール識別子を収集する方法に固有のものです。 Webpackはモジュールのバンドラーであり、モジュールのローダーではないので、それは完璧です。したがって、モジュールローダーを使用する必要があります。現在のところ、実行可能な唯一のオプションはSystemJSです。

次に、各プラグインをモジュールとしてパッケージ化し、すべてのエクスポートコンポーネントをそのモジュールのentryComponentsに追加する必要があります。

実行時に、そのモジュールがロードされると、そのモジュール内に宣言されているコンポーネントにアクセスできます。あなたは実際にはモジュールは必要ありませんが、これはAngularでパッケージ化する単位なので、使用することはできません。今度は、モジュールを取得したら、モジュールがAOTを使ってビルドされているかどうかによってオプションを選択する必要があります。

それはAOTを使用して構築されています場合は、あなただけのモジュールからエクスポートファクトリクラスを取得し、モジュールのインスタンスを作成します。

System.import('path/to/module').then((module)=>{ 
    const moduleFactory = module.moduleFactoryClassName; 
    const moduleRef = moduleFactory.create(this.parentInjector); 
    const resolver = moduleRef.componentFactoryResolver; 
    const compFactory = resolver.resolveComponentFactory(AComponent); 
} 

それはAOTを使用して構築されていない場合は、JITコンパイラを使用して、それをコンパイルする必要があります。

この資料に記載されている技術を使用して好きな場所
System.import('path/to/module').then((module)=>{ 
    const moduleFactory = this.compiler.compileModuleSync(module.moduleClassName); 
    const moduleRef = moduleFactory.create(this.parentInjector); 
    const resolver = moduleRef.componentFactoryResolver; 
    const compFactory = resolver.resolveComponentFactory(AComponent); 
} 

その後は、動的コンポーネントを追加することができます。Here is what you need to know about dynamic components in Angular

+0

あなたのアプローチは、非常に興味深いです使用している可能性がありリモートでホストされているコンポーネント/モジュールをインポートするには? – Seb

+1

@Seb、そうですが、そのためにSystemJSを使用する必要があります –

+0

私のためのトリックをすることができる素晴らしい!あなたはsystemJsとwebpackをどのように統合するかの例を持っていますか?リモートコンポーネントのSystem.importの例 – Seb

関連する問題