2017-11-17 15 views
3

私は非同期ルート解決を終了する方法を探しています。キャンセルルートの解決

シナリオは、ユーザーがコンポーネントに必要なデータを取得するリンクをクリックしたときに、そのユーザーがヒットしたり、別のリンクをクリックしたりするというシナリオです。私は現在の解決を取り消し、新しいルーティングを開始したいと思うでしょう。

既存のルート(まだ解決フェーズにある)が処理中にルートイベントサブスクリプションが起動しないため、これらの変更をリッスンすることでルーティングを傍受することはできません。

const appRoutes: Routes = [ 
{ 
    path: 'resolvableRoute', 
    component: ResolvableRouteComponent, 
    resolve: { 
     data: RouteResolver 
    } 
}]; 

とレゾルバ:私のルータがどのように見えるかもしれ例えば

どのような方法でそのHTTP呼び出しが戻るまで

@Injectable() 
export class RouteResolver implements Resolve<any> { 

    constructor(private http: HttpClient) {} 

    public resolve(router: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> { 
     return this.http.get('api/path/for/data'); 
    } 
} 

、ルータは多かれ少なかれスタックです。

ルートの移行中に起動する素敵なローダーがあり、そのコンポーネントに必要なデータがなくなるまで新しいコンポーネントを表示したくないのですが、リクエストを終了できる必要があります。

例えば、私がリゾルバを使用しなかった場合、コンポーネントはコンポーネントを破棄してhttp要求を終了することができるので、そのコンポーネントがデータを取得している間(たとえばinitで)コンポーネントから移動することができます。このようにコンポーネントを実行することの欠点は、空のページを表示するか、データを取得する処理中に不完全なページを表示することです。

+0

あなたはルートのプロパティを無効にしましたか?リクエストを終了するために使用することができます。 –

+0

CanDeactivateは、ルートがアクティブになっている場合にのみ機能します。ルーティング状態がまだ発火している間に要求を終了する必要があります。本質的にResolveStartとResolveEndの間です。 – crowebird

+0

はこの答えが役に立つかもしれません..https://stackoverflow.com/questions/36490926/how-to-cancel-a-httprequest-in-angular-2 –

答えて

0

私はこれを解決するために私の解決策を投稿するつもりです。この解決策は私が必要とするもので、多分他の人を助けるものです。

このソリューションの欠点は、私が必要としないルータ用のラッパーが必要なことです。

理想的には、私はルータのナビゲーションキューへのサブスクリプションを作成できましたが、これらのメソッド/変数はすべて角度ルータでプライベートなので、アクセスできませんでした。

代わりに、私はときに新しいナビゲーション・イベントが発生し、私はイベントをトリガすることができますRouterService作成:(通常はhttpリクエストを返すように望んでいることを)私の解決の内側に私が観測を作成した後

@Injectable() 
export class RouterService { 

    protected navigateListener = new EventEmitter<any>(); 

    constructor(private router: Router) {} 

    public subscribe(generatorOrNext?: any, error?: any, complete?: any) { 
     return this.navigateListener.subscribe(generatorOrNext, error, complete); 
    } 

    public navigate(commands: any[], extras?: NavigationExtras): Promise<boolean> { 
     this.navigateListener.next(); 
     return this.router.navigate(commands, extras); 
    } 

    public navigateByUrl(url: string | UrlTree, extras?: NavigationExtras): Promise<boolean> { 
     this.navigateListener.next(); 
     return this.router.navigateByUrl(url, extras); 
    } 

} 

を、しかし、また、RouterServiceのイベントの変更をリッスンしています。ルートナビゲーションが発信された場合は、httpリクエストを終了し、約束が完了することを知らせます。

public resolve(router: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<any> { 
     return new Promise((resolve: any, reject: any) => { 
       const subscription = this.http.get('/path/to/some/url').subscribe((data) => { 
        resolve(data) 
       }, (error) => { 
        reject({ 
         ngNavigationCancelingError: true 
        }); 
       }); 

       this.router.subscribe(change => { 
        subscription.unsubscribe(); 
        reject({ 
         ngNavigationCancelingError: true 
        }); 
       }); 
     }); 
    }