2016-06-17 2 views
3

라우터 모듈 v 3.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를 돌려주는 경우, 탐색 프로세스가 계속가, 탐색 프로세스가 중지되고 사용자는 도 말할 수 가드를 머물러 :

가드의 반환 값은 라우터의 동작을 제어 라우터가 다른 곳으로 이동하여 현재 탐색을 효과적으로 취소합니다.

guard는 부울 답변을 동 기적으로 반환 할 수 있습니다. 그러나 많은 사례에서 가드가 동기식으로 응답을 생성 할 수 없습니다. 관리자 은 사용자에게 질문하거나, 서버에 변경 사항을 저장하거나, 신선한 데이터를 가져올 수 있습니다. 이것들은 모두 비동기 작업입니다.

따라서 라우팅 가드는 Observable을 반환 할 수 있으며 라우터는 관찰 가능 항목이 true 또는 false로 확인 될 때까지 대기합니다.

당신은 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

깔끔한!다시 한 번 감사드립니다 –

관련 문제