2016-06-17 3 views
3

В angular2 rc2 с модулем маршрутизатора v 3.0.0.6alpha я расширяю RouterOulet, чтобы проверить, вошел ли пользователь в систему, прежде чем обращаться к администратору. Так что это код:Angular2 - Расширяющийся роутер и наблюдаемый

@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(nextInstruction: ComponentInstruction) : Promise<any>

@ Угловой/маршрутизатор

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

, которая не является обещанием или Наблюдаемым больше. Новая реализация маршрутизатора имеет немного другое решение, которое я считаю более чистым: Guard.

возвращаемого значение охранника контролирует поведение маршрутизатора:

, если она возвращает истину, процесс навигации продолжается, если он возвращает лжи, процесс навигации останавливается, и пользователь остается на месте Стража также может сказать маршрутизатор для навигации в другом месте, эффективно отменяя текущую навигацию.

Охранник может возвращать свой логический ответ синхронно. Но во многих случаях охранник не может дать ответ синхронно. Охранник может задать пользователю вопрос, сохранить изменения на сервере или извлечь свежие данные. Это все асинхронные операции.

Соответственно, защитник маршрутизации может возвращать Наблюдаемый, а маршрутизатор будет ожидать, что наблюдаемое будет разрешено 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 Reference является 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

Уход!Еще раз спасибо –

Смежные вопросы