2016-06-17 7 views
3

router2のv3.0.0.6alphaでangular2 rc2を使用している場合、ユーザーにログインしていることを確認するためにRouterOuletを拡張します。これはコードです:Angular2 - ルーターとObservableを拡張する

@Directive({ 
    selector: 'router-outlet' 
}) 

export class LoggedInRouterOutlet extends RouterOutlet 
{ 
    publicRoutes: Array<string>; 
    private parentOutletMap: RouterOutletMap; 
    private userService: UserService; 
    private parentRouter: Router; 

    constructor(
     parentOutletMap: RouterOutletMap, 
     _location: ViewContainerRef, 
     @Attribute('name') name: string, 
     userService: UserService, 
     parentRouter: Router 
    ) { 
     super(parentOutletMap, _location, name); 

     this.parentRouter = parentRouter; 
     this.parentOutletMap = parentOutletMap; 
     this.userService = userService; 
     this.publicRoutes = [ 
      'public', 
      'login' 
     ]; 
    } 

    activate(factory: ComponentFactory<any>, activatedRoute: ActivatedRoute, providers: ResolvedReflectiveProvider[], outletMap: RouterOutletMap) 
    { 
     if (this._canActivate(factory.selector)) { 
      return super.activate(factory, activatedRoute, providers, outletMap); 
     } 

     this.parentRouter.navigate(['/login']); 
    } 

    _canActivate(url) { 
     return this.publicRoutes.indexOf(url) !== -1 || this.userService.isLoggedIn() 
    } 
} 

userService.isLoggedIn()はブール値を返す必要があります。私の質問は次のとおりです。ユーザーがログインしているかどうかを確認するためにhttp呼び出しを行うために自分のコードを適合させるにはどうすればよいですか? isLoggedInメソッドが観察可能なオブジェクトを返し、それをサブスクライブすると、親関数で結果を返すことができないためです。

答えて

8

OutletRouterのactivateメソッドの結果が変更されていることに注意してください。 @

角度/ルータ、廃止予定の角度@

activate(nextInstruction: ComponentInstruction) : Promise<any>

/ルータの約束またはそれ以上の観察可能ではありません

activate(factory: ComponentFactory<any>, providers: ResolvedReflectiveProvider[], outletMap: RouterOutletMap) : ComponentRef<any>

。新しいルータの実装には、より洗練されたと思われる少し異なる解決策が付属しています:ガード。それは falseを返した場合

それがtrueを返した場合、ナビゲーション処理が続くが、ナビゲーション処理が停止し、ユーザーが も伝えることができ、ガードを入れたまま:

ガードの戻り値は、ルータの動作を制御しますルータは他の場所をナビゲートし、効果的に現在のナビゲーション をキャンセルします。

ガードは、ブール型の応答を同期して返すことがあります。しかし多くの場合、 の場合、ガードは同期して応答を生成することはできません。ガード は、ユーザーに質問をしたり、サーバーに変更を保存したり、新鮮なデータを 取得することができます。これらはすべて非同期操作です。

したがって、ルーティングガードはObservableを返すことができ、ルータはオブザーバブルが真または偽に解決されるのを待機します。

あなたはauth.guard.tsを作成することができます。

import { Injectable }    from '@angular/core'; 
import { CanActivate, 
     Router, 
     ActivatedRouteSnapshot, 
     RouterStateSnapshot } from '@angular/router'; 
import { UserService }   from './user.service'; 

@Injectable() 
export class AuthGuard implements CanActivate { 
    constructor(private userService: UserService, private router: Router) {} 

    canActivate(
    // Not using but worth knowing about 
    next: ActivatedRouteSnapshot, 
    state: RouterStateSnapshot 
) { 
    return this.userService.isLoggedIn(); 
    } 
} 

は、今すぐあなたのisLoggedInが観察返すことを確認します(または約束 - Angular2リファレンスnot ready yetあるとして両方を試してみてください)。私の場合、APIはJSONを{success:true/false}の形式で返します。

public isLoggedIn() : Observable<boolean> | boolean { 
    let router: Router = this.router; 
    let obs; 

    try { 
     obs = this.authHttp.get('/api/check/logged') 
      .map(result => result.json()) 
      .map(resultJson => (resultJson && resultJson.success)); 

    } catch (err) { 
     obs = Observable.of(false); 
    } 

    return obs 
     .map(success => { 
      // navigate to login page 
      if (!success) 
       router.navigate(['/auth/login']); 

      return success; 
     }); 
} 

は、それからちょうどあなたのRouterConfigの配列を変更:

{ path: '/secret', component: SercetComponent, canActivate: [AuthGuard] } 

は、Angular2 Developer Guide

+0

良いようだにも感謝を参照してください!しかし、私はそのガードをどこに注入するのだろうか?あなたがコードを編集してそれを表示できるのであれば... –

+0

元の回答を投稿してから数分しました;)これを前に追加するのを忘れました。 – Baumi

+0

ニート!もう一度おねがいします –

関連する問題