2017-12-01 5 views
3

私はかなり一般的ではないかもしれないことをしようとしています。私はAngularを多くの外部依存関係を必要とせずに最高の状態で利用しようとしていますが、要件の理由から、日付範囲ピッキング(this one)には非常に特殊なライブラリを使用する必要がありますが、JQueryとMoment.js、これはすでに追加されています)。依存関係を遅延ロードした後に、実行時にAngular 5コンポーネントを作成する

この場合、JQueryとMoment.jsをページに簡単に読み込むことができますが、これは賢明なアプローチではないようです。バンドルのサイズが大きくなり、このアプリケーションをできます。

次に、私は考えに入りました:なぜこれらの依存関係を遅延ロードせずにコンポーネントをインスタンス化するのですか?良いアプローチのようですね。

私はCDNのドキュメントスクリプトに含めることができるプロバイダを使用していますが、うまくいきます。しかし、今ではどうにかしてを挿入するこのdaterangepickerコンポーネントは、実行時に、両方のライブラリがロードされて約束を解決しています。

現状: -

1私は、実行時に私の依存関係(jQueryとMoment.js)をロードし、この親クラス、持っている:

import { Component, OnInit } from '@angular/core'; 
import { LibraryLazyLoader } from '../../../providers/library_lazy_loader'; 
import { Ng4LoadingSpinnerService } from 'ng4-loading-spinner'; 

@Component({ 
    selector: 'date-selector', 
    templateUrl: './date-selector.component.html', 
    styleUrls: ['./date-selector.component.css'], 
    providers: [LibraryLazyLoader] 
}) 
export class DateSelectorComponent implements OnInit { 

    isLoaded = false; 

    constructor(
    private libraryLoader:LibraryLazyLoader, 
    private loadingSpinner:Ng4LoadingSpinnerService 
){ 
    this.loadingSpinner.show(); 
    this.libraryLoader.loadJs('https://code.jquery.com/jquery-3.2.1.min.js') 
     .subscribe(() => { 
      console.log("JQuery included"); 
      this.libraryLoader.loadJs('https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.3/moment.min.js') 
      .subscribe(() => { 
       console.log("Moment.js included"); 
       this.loadingSpinner.hide(); 
       this.isLoaded = true; 
      }) 
     }) 
    } 

    ngOnInit() { 

    } 

} 

2 - それは、テンプレートされますただ、このように:

<button>Load js</button> 
<div *ngIf="isLoaded"> 
    <input daterangepicker> 
</div> 

アイデアは、両方のライブラリがロードされたときに、isLoadedブールはデートで更新するビューを引き起こすべきですangepickerディレクティブが正しく読み込まれ、コンポーネントを使用して私を許可します。

これは機能しません。私はこのプロジェクトでこれを使用するつもりはありませんが、もっとうまく最適化されたページを作ることができるので、それがうまくいくかどうか不思議です!レイジーローディングモジュールは素晴らしいですが、次のステップはコンポーネントを遅延させることです。このアプローチがうまくいかないと誰かが私を修正しますが、それはAngularにとって本当に良い改善になると思います。

だから、どんなアイデアですか?

+0

こんにちは@Zerok、なぜこれは動作しません? –

答えて

2

アイデアと同じように、ルートにスクリプトをロードするガードを追加し、スクリプトがロードされるとコンポーネントをロードすることができます。

Angularドキュメンテーションの例を拡張します。あなたはちょうど私が問題が上記のあなたの例では何かわからない、また彼らに

@Injectable() 
class TeamResolver implements Resolve<any> { 

    resolve(
    route: ActivatedRouteSnapshot, 
    state: RouterStateSnapshot 
): Observable<any>|Promise<any>|any { 
    return Promise.all([ 
import("https://code.jquery.com/jquery-3.2.1.min.js"), 
import("https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.3/moment.min.js") 
]) 
    } 
} 

@NgModule({ 
    imports: [ 
    RouterModule.forRoot([ 
     { 
     path: 'team/:id', 
     component: TeamCmp, 
     resolve: { 
      team: TeamResolver 
     } 
     } 
    ]) 
    ], 
    providers: [TeamResolver] 
}) 
class AppModule {} 

を必要とするビューに移動する前に、依存関係を解決するためにガードを追加することができますか?あなたは何も起こっていないと思っていますが、Angularにサイクルをもう一度やり直す必要があると言います。たぶんお試しください

setTimeout(() => { 
    this.loadingSpinner.hide(); 
    this.isLoaded = true; 
}) 
+0

例を追加できますか? – Zerok

関連する問題