http响应后没有触发Angular2 event.next

时间:2016-06-26 16:06:52

标签: javascript-events angular observable

我有一个奇怪的情况。我有导航组件,我只想在用户登录时显示。我试图使用默认为false的变量来管理它,当用户登录时,值为true且菜单可见。

目前的情况是,当用户点击MenuComponent上的注销链接时,会发出事件并更改值。但是在登录时,在http响应之后,它没有被触发。

这是菜单组件:

import { Component, OnInit } from '@angular/core';
import { UserService } from './../user/user.service';
import { Router } from '@angular/router';

@Component({
  moduleId: module.id,
  selector: 'app-navigation',
  templateUrl: 'navigation.component.html',
  styleUrls: ['navigation.component.css'],
  providers: [UserService]
})
export class NavigationComponent implements OnInit {
  public menuStatus;
  constructor(private userService: UserService, private router: Router) {
    this.menuStatus = userService.isLoggedIn();
  }
  ngOnInit() {
    this.userService.userLoggedOut$.subscribe(data => {
      console.log('userLoggedOut subscribe');
      this.menuStatus = data;
    });

    this.userService.userLoggedIn$.subscribe(data => {
      console.log('userLoggedIn subscribe');
      this.menuStatus = data;
    });
  }
  logout() {
    this.userService.userLogout();
    this.router.navigate(['/login']);
  }
}

在此,注销按钮单击触发注销功能。用户服务userLogout函数具有事件发射器。这是事件发射器:

import {Injectable} from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { Subject } from 'rxjs/Subject';
import { Config } from './../shared/config';

@Injectable()
export class UserService {
  private loggedIn;
  private userLoginUpURL;
  private userLoggedInEvent = new Subject();
  private userLoggedOutEvent = new Subject();

  userLoggedIn$ = this.userLoggedInEvent.asObservable();
  userLoggedOut$ = this.userLoggedOutEvent.asObservable();

  constructor(private http: Http, private config: Config) {
    this.loggedIn = false;
    this.loggedIn = !!localStorage.getItem('access_token');
    this.userLoginUpURL = this.config.loginUrl;
  }

  getUserObject() {
    return JSON.parse(localStorage.getItem('user_object'));
  }

  userLogin(userLoginDetails) {
    let headers = new Headers({
      'Content-Type': 'application/json'
    });

    let postData = {
      email: userLoginDetails.email,
      password: userLoginDetails.password
    };

    return this.http
      .post(this.userLoginUpURL, JSON.stringify(postData), {headers: headers})
      .toPromise()
      .then(res => {
        localStorage.setItem('access_token', res.json().access_token.access_token);
        localStorage.setItem('user_object', JSON.stringify(res.json().user));
        this.loggedIn = true;
        this.userLoggedInEvent.next(this.loggedIn);
        return res.json();
      })
      .catch(this.handleError);
  }

  userLogout() {
    // destroy the local storage variabled
    localStorage.removeItem('access_token');
    localStorage.removeItem('user_object');

    // setup the login status to false
    this.loggedIn = false;
    this.userLoggedOutEvent.next(false);
  }

  isLoggedIn() {
    return this.loggedIn;
  }

  private handleError(error: any) {
    return Promise.reject(error.message || error);
  }
}

问题是,在我调用this.userLoggedInEvent.next(this.loggedIn)时登录后,事件不会触发。

有人可以帮忙。有一个简单的解决方法,我可以刷新窗口并将用户重定向到仪表板,但我不想刷新页面并以正确的方式执行。请帮忙。

1 个答案:

答案 0 :(得分:1)

确保您只在公共父级(根组件)上提供UserService一次,否则不同的组件将获得不同的实例并在一个实例上进行侦听,而在另一个实例上进行排放将无法实现太多; - )