除非我进行页面刷新,否则无法获得BehaviorSubject的正确值

时间:2017-12-15 22:39:59

标签: angular partial-page-refresh behaviorsubject

我的BehaviorSubject无法将新值推给我的观察者。我完成了本教程https://netbasal.com/angular-2-persist-your-login-status-with-behaviorsubject-45da9ec43243,但没有运气。我也试图在SO和博士身上找到一些东西。谷歌,但也没有运气。 我不知道自己做错了什么。

这是我的Authservice代码和与之交互的组件。

的AuthenticationService

import { BehaviorSubject, Observable } from 'rxjs/Rx';
import { Http, Response } from '@angular/http';
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';

@Injectable()
export class AuthenticationService {
  private _url = '/api';
  private _user$: BehaviorSubject<string>;
  private _isLoggedIn: BehaviorSubject<boolean>;

  public redirectUrl: string;

  constructor(private http: Http) {
    const currentUser = JSON.parse(localStorage.getItem('currentUser'));
    this._user$ = new BehaviorSubject<string>(currentUser && currentUser.email);
    this._isLoggedIn  = new BehaviorSubject<boolean>(this.hasUser());
  }

  get user$(): BehaviorSubject<string> {
    return this._user$;
  }

  isLoggedIn(): Observable<boolean> {
    return this._isLoggedIn.asObservable();
  }

  hasUser() {
    return !!localStorage.getItem('currentUser')
  }

  get token(): string {
    const localCurrentUser = JSON.parse(localStorage.getItem('currentUser'));
    return !!localCurrentUser ? localCurrentUser.token  : '';
  }

  login(email: string, password: string): Observable<boolean> {
    return this.http.post(`${this._url}/login`, { email: email, password: password })
      .map(res => res.json()).map(res => {
        const token = res.token;
        if (token) {
          localStorage.setItem('currentUser', JSON.stringify({ email: email, token: token }));
          this._user$.next(email);
          this._isLoggedIn.next(true);
          return true;
        } else {
          return false;
        }
      });
  }

  logout() {
    if (this.user$.getValue()) {
      localStorage.removeItem('currentUser');
      setTimeout(() => this._user$.next(null));
      this._isLoggedIn.next(false)
    }
  }

  register(email: string, password: string): Observable<boolean> {
    return this.http.post(`${this._url}/register`, { email: email, password: password })
      .map(res => res.json()).map(res => {
        const token = res.token;
        if (token) {
          localStorage.setItem('currentUser', JSON.stringify({ email: email, token: res.token }));
          this._user$.next(email);  
          this._isLoggedIn.next(true)    
          return true;
        } else {
          return false;
        }
      });
  }
}

nav.component.ts

    import { Observable } from 'rxjs/Rx';
import { Component, OnInit } from '@angular/core';
import { AuthenticationService } from '../user/authentication.service';

@Component({
  selector: 'app-nav',
  templateUrl: './nav.component.html',
  styleUrls: ['./nav.component.css'],
  providers: [AuthenticationService]
})
export class NavComponent implements OnInit {
  private _isLoggedIn: Observable<boolean>

  constructor(private auth: AuthenticationService) {
      this._isLoggedIn = auth.isLoggedIn();
  }

  ngOnInit() { 
  }

  get isLoggedIn() {
    return this._isLoggedIn
  }

}

nav.component.html 仅显示问题代码*

<li class="nav-item" *ngIf="!(isLoggedIn | async)"><a class="nav-link" href="#"
      routerLink="/login">Login</a></li>
      <li class="nav-item" *ngIf="!(isLoggedIn | async)"><a class="nav-link" href="#"
      routerLink="/register">Register</a></li>
      <li class="nav-item" *ngIf="(isLoggedIn | async)"><a class="nav-link" href="#"
      routerLink="/logout">Logout</a></li>
    </ul>

navcomponent是app模块的一部分,authservice是用户模块的一部分

user.module.ts

import { AuthGuardService } from './auth-guard.service';
import { AuthenticationService } from './authentication.service';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LoginComponent } from './login/login.component';
import { LogoutComponent } from './logout/logout.component';
import { RegisterComponent } from './register/register.component';
import {RouterModule, Routes} from '@angular/router';


const userRoutes: Routes = [
  {path: 'login', component: LoginComponent},
  {path: 'register', component: RegisterComponent},
  {path: 'logout', component: LogoutComponent}
];

@NgModule({
  imports: [
    HttpModule,
    ReactiveFormsModule,
    CommonModule,
    RouterModule.forChild(userRoutes)
  ],
  declarations: [
    LoginComponent,
    LogoutComponent,
    RegisterComponent
  ],
  providers: [
    AuthenticationService,
    AuthGuardService
  ]
})
export class UserModule { }

app.module.ts

import {HttpModule} from '@angular/http';
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {AppComponent} from './app.component';
import {NavComponent} from './nav/nav.component';
import {AppRoutingModule} from './app-routing/app-routing.module';
import {NavdropdownDirective} from './nav/navdropdown.directive';
import {PageNotFoundComponent} from './page-not-found/page-not-found.component';
import {RegistrationModule} from './registration/registrations.module';
import {ScheduleModule} from './schedule/schedule.module';
import {PreferencesModule} from './preferences/preferences.module';
import {UserModule} from './user/user.module';

@NgModule({
  declarations: [
    AppComponent,
    NavComponent,
    NavdropdownDirective,
    PageNotFoundComponent
  ],
  imports: [
    HttpModule,
    BrowserModule,
    UserModule,
    RegistrationModule,
    ScheduleModule,
    PreferencesModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {
}

我希望有人可以帮助我解决我做错的事情。

  

帮助我Obi-one Kenobi,你是我唯一的希望 - Lea公主,一个新的希望

1 个答案:

答案 0 :(得分:0)

当您返回此代码中的Observable时:

  isLoggedIn(): Observable<boolean> {
    return this._isLoggedIn.asObservable();
  }

调用代码需要订阅。

  ngOnInit() { 
    this.auth.isLoggedIn().subscribe(value => this._isLoggedIn = value);
  }

对于你正在做的事情,使用BehaviorSubject有点矫枉过正。由于isLoggedIn绑定在UI中,因此它将自动处理更改通知。你真正需要的只是一个简单的布尔属性:

验证服务

this.isLoggedIn: boolean = false;

导航组件

export class NavComponent implements OnInit {

  constructor(private auth: AuthenticationService) {

  }

  ngOnInit() { 
  }

  get isLoggedIn() {
    return this.auth.isLoggedIn;
  }

}

只要服务中的isLoggedIn状态发生变化,更改检测就会获取更改,UI会相应调整。