2016-12-08 14 views
2

私は、http-service(ユーザと彼の役割に関するデータ)を介してサーバからロードされるいくつかのデータに依存する複数のコンポーネントでAngular 2アプリを開発しています。ルータ出口の角度2遅延レンダリング

このデータがまだロードされていない場合、ほとんどのルートコンポーネントがngOnInit()メソッド内でエラーをスローします。データは、すべてのコンポーネントで注入されたサービス内にロードされて格納されます。

httpコールが終了するまで、ルートコンポーネント内の現在のルートのレンダリングを遅延させる方法はありますか?

それ以外の場合は、すべてのルートコンポーネントのngOnInit内で何らかのチェックと再試行のメカニズムを実装する必要があります。これは非常に面倒です。

私はすでに、コールが終了するまで、ルータ、アウトレット要素を隠そうとしたが、これは作成するときに、ルータの初期ナビゲーションを遅らせるためのオプションがあり

+0

サービスは同じeverwhereのですか?もしそうなら、APP_INITIALIZERを使ってこの問題を処理することができます – Sakuto

+1

'Resolve'クラスを使用し、コンポーネントのデータプロバイダとして' Resolver'を作成すると、コンポーネントが初期化される前にデータを収集します。 – ulubeyn

答えて

4

を「XXXをロードするための第一出口を見つけることができません」というエラーにつながります

this.router.initialNavigation(); 
3

私はこれを達成します。Routerモジュール:このよう

RouterModule.forRoot([ 
    // routes here 
], { 
    initialNavigation: false // the propery to delay navigation 
}), 

後の最初のナビゲーションは、角度のルータを経由してトリガすることができますCanActivateガードでCanActivateメソッドからObservableを返すことが重要です。そうすれば、あなたが必要とする限り遅延することができます。上記

import { CanActivate } from '@angular/router'; 
import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Rx'; 
import { StateService } from '../../_services/state.service'; 
import { Subject } from 'rxjs/Rx'; 
import { Subscription } from 'rxjs/Subscription'; 

@Injectable() 
export class LoadingGuard implements CanActivate { 
    constructor(private state: StateService) {} 

    public canActivate(): Observable<boolean> { 
     if (!this.state.loading$.getValue()) { 
      return Observable.of(true); 
     } 

     let subject = new Subject<boolean>(); 
     let subscription = this.state.loading$.subscribe(value => { 
      if (!value) { 
       subject.next(true); 
       subject.complete(); 

       subscription.unsubscribe(); 
      } 
     }); 

     return subject; 
    } 
} 

、StateServiceは、アプリの残りのため、現在のユーザーとプリキャッシュいくつかのデータを評価するサービスです。ロード完了後にfalseを返すサブジェクトloading$があります。

残っているのは、アプリケーションモジュールでガードを宣言することです。

import { LoadingGuard } from './app/loading-guard/loading-guard'; 
// other imports omitted 

@NgModule({ 
    // other module properties omitted 
    providers: [LoadingGuard] 
}) 
export class AppModule {} 

ルーティングでガードを宣言してください。参考のため

import { LoadingGuard } from './app/loading-guard/loading-guard'; 
// other imports omitted 

export const rootRouterConfig: Routes = [ 
    { path: 'app', component: AppComponent, 
     canActivate: [LoadingGuard], 
     children: [ 
     { path: 'index', component: IndexComponent }, 
     // child routes omitted 
     ] }, 
    { path: 'sign-in', component: SignInComponent }, 
    { path: '**', redirectTo: 'sign-in' } 
]; 

、ここCanActivateのドキュメントです: https://angular.io/docs/ts/latest/api/router/index/CanActivate-interface.html