订阅ReplaySubject并不起作用

时间:2017-05-31 12:53:01

标签: angular rxjs

我的身份验证

public currentUser: ReplaySubject<User> = new ReplaySubject<User>(1);

当用户登录时我使用

  public setCurrentUser(user: User) {
    this.currentUser.next(user);
  }

设置用户对象。

CanActivateGuard存在问题,我认为不会以某种方式看到currentUser

这是代码

import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
import { AuthService } from './auth.service';

import {User} from '../models/user';


@Injectable()
export class CanActivateGuard implements CanActivate {
  private logged: boolean = false;

  constructor(
    private router: Router,
    public _auth: AuthService
  ) {
    console.log('CanActivateGuard');

    this._auth.currentUser.subscribe(
      (user) => {
        this.logged = user.logged;
        console.log('user');
        console.log(user);
      },
      (error) => {
        console.log(error);
      }
    );
  }

  public canActivate() {

    if ( !this.logged ) {
       this.router.navigate( [ 'login' ] );
    }
    console.log(this.logged);
    return this.logged;
  }
}

它永远不会到达this.logged = user.logged;我认为它看到这个._auth.currentUser为空

这是整个项目的链接:https://github.com/MoustafaElkady/You360-Web-Client/tree/master/src/app

1 个答案:

答案 0 :(得分:4)

canActivate可以返回Observable<boolean>,这会让生活更加直接。您不需要在构造函数中订阅服务的主题,您可以构建一个observable并让路由器订阅结果。

@Injectable()
export class CanActivateGuard implements CanActivate {
  constructor(
    private router: Router,
    private auth: AuthService,
  ) { }

  public canActivate(): Observable<boolean> {
    return this.auth.currentUser
        .map(user => user.logged)  // extract logged property from user
        .catch(() => Observable.of(false))  // assume not logged in if error
        .do(loggedIn => {
          if (!loggedIn) {
            this.router.navigate(['login']);  // navigate if not logged in
          }
        }); 
  }
}

我建议您阅读appropriate documentation;它很长,但路由器中有很多事情发生。

我还建议不要从服务中自行创建主题public;这意味着其他东西可以将数据推入其中。我写了一篇关于使用私人主题和公共观察的博客文章,你可能会发现它很有用:Handling data with the Angular AsyncPipe