1

我的 BehaviorSubject 没有向我的观察者推送它的新价值时遇到了麻烦。我遵循了本教程https://netbasal.com/angular-2-persist-your-login-status-with-behaviorsubject-45da9ec43243但没有运气。我还试图在 SO 和博士上找到一些东西。谷歌,但也没有运气。我不知道我做错了什么。

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

认证服务

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;
        }
      });
  }
}

导航组件.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 模块的一部分

用户模块.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,你是我唯一的希望 - 莉亚公主,新的希望

4

1 回答 1

1

当您在此代码中返回 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 会相应地进行调整。

于 2017-12-15T22:49:31.967 回答