2017-11-03 17 views
1

私は約1年で2/4の角度を使用してきましたが、ルータをサービス中に注入することが悪い習慣であると考えられるかどうかは、このジレンマに戻り続けますか?角度4のサービスでルータを使用

これはよりアーキテクチャ上の問題です。私はそれに対して正確な答えはないと信じていますが、私はあなたの意見を聞きたいです。ここに2つの例があります。

  1. 次のコードを検討してください。いくつかの要素があるとしたら、ある行動の後にユーザーを特定の経路にリダイレクトしたいとします。ユーザーが新しいエンティティを追加したので、彼をグリッドにリダイレクトする必要があります。

component.ts

constructor(private router: Router) {} 

someAction() { 
    // Some code here 
    this.router.navigate(['/grid']); 
} 

は、ここで私は、ルータおよびコンポーネントの両方がUI層であるので、それは、ルータを使用するように完全に罰金だと思います。

  1. 次に、auth.service.tsがあり、それが認証を担当しているとしましょう。私たちはアプリケーションからユーザをログアウトさせたいと思っており、それを行うにはlogout()の機能があります。

auth.service.ts

constructor(private router: Router) {} 

logout() { 
    // Cleanup token, storage, etc. 
    this.router.navigate(['/login']); 
} 

だから建築思考:

  1. あなたはサービス内の、このようなルータの使用状況をどう思いますか?
  2. これは有効なアプローチだと思いますか?
  3. この場合、あなたは何を提案していませんか?

私はauthServiceeventEmitterを置くことを考えると、例えばapp.component.tsの内側にそれを購読するが、それはサービスでそれを持つよりはましだ場合は、まだわかりませんでした。

このケースのコメントはありがたいです。どうもありがとう!

EDIT

別の例は:UIは、タスクとカレンダーです。

すべてのデータフローを処理し、カレンダーのデータを提供するサービスがあります。カレンダー自体はデータを要求するのではなく、サービスからのデータ変更をサブスクライブします。

今、このカレンダーから別の画面にユーザーをルーティングする必要があります。次の週/月/年のユーザークリックを想像してください。

このデータはルートURLに保存されるため、ユーザーはページの更新後も同じ日に滞在できますが、カレンダーコンポーネントは日/週/月を認識しません。

サービス内でカプセル化されています。この場合、サービスでルータを使用しますか?

+0

最後の例では、ユーザーが予定の詳細にアクセスする方法、または予定表からナビゲートする方法について教えてください。私の場合、彼はその日にクリックして、この日の特定の内訳を取得したいとの相互作用について質問しています – Sonicd300

+0

コンポーネントの中で私は自分のサービスで 'fetchDay()'を呼び出します。だから、基本的に私はサービスにデータをフェッチするよう依頼するが、同時にユーザーを次の画面にリダイレクトする必要があるが、ルートを計算するためにはサービスからの非カプセル化データが必要である。 –

+1

サブスクライブ内で仕事をすることはできますか? fetchDay()では、データを取得するサービスを呼び出すコンポーネントに初期化ロジックを持つカレンダーをレンダリングし、データが正常に処理された後はいつでもコンポーネントからルーティングできます。カレンダー。 – Sonicd300

答えて

3

TL:いつも部品からやっている方が良いです。可動部分がどこにあるのかを知ることができるからです。サービスではより湿っていますが、常に確認するのは難しいです。成分。

あなたがその目的とインターセプタのためにガードを使用することができます

、私は401を取得するときにログアウトするルートに、次のようなエラーインターセプタを追加しました:

import { Injectable } from '@angular/core'; 
import { HttpEvent, HttpErrorResponse, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'; 
import { Router } from '@angular/router'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/observable/throw'; 
import 'rxjs/add/operator/catch'; 

@Injectable() 
export class ErrorInterceptor implements HttpInterceptor { 
    constructor(private router: Router) {} 

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { 
    return next.handle(req).catch(
     (err: HttpErrorResponse) => { 
     if (this.router.url !== '/login' && err.status === 401) { 
      this.router.navigate(['/logout']); 
     } 
     return Observable.throw(err); 
     } 
    ); 
    } 
} 

あなたのアプリでそれを提供、あなたがサービス中のルーティング配置する必要はありませんあなたがします.moduleまたは私の場合、私はこのようなもので、私のapp.moduleクリーン

{ 
    provide: HTTP_INTERCEPTORS, 
    useClass: ErrorInterceptor, 
    multi: true 
} 

を維持するために、すべてのシングルトンのためcore.moduleを作成しましたから401を得るトークンが無効な場合のAPI

このコードを少し修正して、可能な限り一般的なものにしようとしたかもしれません。

+0

あなたの答えをありがとう!はい、それは有望に見えます。しかし、この場合、システムからユーザーをログインページに呼び出すために、次の応答を待つ必要があります。私はすぐに何かを考えていた。ユーザーメニューの[ログアウト]をクリックしたときと同じです。たぶん、これが最良の例ではないかもしれません。一般的な質問は、ルータを稼動させるのが悪い習慣だと思いますか? –

+0

私がやってきたやり方は、ログアウトする経路にテンプレートのボタン/リンクがあるということです。ログアウトは、認証サービスを呼び出してセッションを終了するコンポーネントです(ユーザーがログアウトしたと仮定した場合) – Sonicd300

+1

わかります。再度、感謝します!ええ、私は通常同じようにします。元の質問を別の例で編集する必要があると思います。 –

関連する問題