BehaviorSubject 的订阅者未检测到更改

Subscribers to BehavorSubject not deteciting chanfes

我正在使用异步工作的 localforage 服务。我已经创建了自己的服务来管理所有关于 localforage 数据的信息。此服务添加到 appmodule 是全局的。

我遇到的问题是,即使我已经订阅了 er,ew,eu,ed BehavorSubject 变量,此变量的订阅者未检测到更改或未收到更改通知。此变量是应用程序中用户的权限(布尔值),以便 show/hide 根据此权限

进行一些操作

我的app.module.ts:

providers: [appRoutingProviders, AuthGuard, BnNgIdleService, IndexedDBService, {
    provide: HTTP_INTERCEPTORS,
    useClass: TokenInterceptorService,
    multi: true
  }],

我的 IndexedDBService:

import { AfterViewInit, Injectable, OnInit } from "@angular/core";
import { LocalForageService } from "ngx-localforage";
import { BehaviorSubject, Observable, ReplaySubject, Subject } from "rxjs";

//@Injectable({ providedIn: 'root' })
export class IndexedDBService implements OnInit{

   private isLoading: BehaviorSubject<boolean> 
   private er: BehaviorSubject<boolean> = new BehaviorSubject(false); 
   private ew: BehaviorSubject<boolean> = new BehaviorSubject(false);
   private eu: BehaviorSubject<boolean> = new BehaviorSubject(false);
   private ed: BehaviorSubject<boolean> = new BehaviorSubject(false);

   constructor(
      private localforage: LocalForageService
   ){
      this.isLoading = new BehaviorSubject(false);
   }

   ngOnInit(): void {
      this.getUsrPrivileges();
   }

   public showSpinner(){
      this.isLoading.next(true);
   }

   public hideSpinner(){
      this.isLoading.next(false);
   }

   public isPageLoading(){
      return this.isLoading;
   }

   public setToken(token: string){
      this.localforage.setItem('token',token);
   }

   public getToken(){
      return this.localforage.getItem('token')
   }

   public clearLocalForage(){
      return this.localforage.clear().toPromise();
   }

   public getER(): Observable<boolean>{
      return this.er.asObservable();
   }

   public setER(er: boolean){
      this.er.next(er);
      this.localforage.setItem('er',er);
   }

   public setEW(ew: boolean){
      this.ew.next(ew);
      this.localforage.setItem('ew',ew);
   }

   public getEW(): Observable<boolean>{
      return this.ew.asObservable();
   }

   public setEU(eu: boolean){
      this.eu.next(eu);
      this.localforage.setItem('eu',eu);
   }

   public getEU(): Observable<boolean>{
      return this.eu.asObservable();
   }

   public setED(ed: boolean){
      this.ed.next(ed);
      this.localforage.setItem('ed',ed);
   }

   public getED(): Observable<boolean>{
      return this.ed.asObservable();
   }

   getUsrPrivileges(){
      this.localforage.getItem('er').subscribe(value => this.er.next(value));
      this.localforage.getItem('ew').subscribe(value => this.ew.next(value));
      this.localforage.getItem('eu').subscribe(value => this.eu.next(value));
      this.localforage.getItem('ed').subscribe(value => this.ed.next(value));
   }
}

在我的 LoginAppComponent 中,我获得并填写了用户权限:

...

constructor(
  ...
  private _indexedDBService: IndexedDBService,
  ...
) { 

}

setUsrPrivileges(privilegios: string){
  let er = privilegios.substring(0,1) === '1';
  let ew = privilegios.substring(1,2) === '1';
  let eu = privilegios.substring(2,3) === '1';
  let ed = privilegios.substring(3,4) === '1';

  this._indexedDBService.setER(er);
  this._indexedDBService.setEW(ew);
  this._indexedDBService.setEU(eu);
  this._indexedDBService.setED(ed);
}

...

在我的应用程序菜单中,我有订阅者订阅了 IndexedDBService 的这个 er,ew,eu,ed 值,必须通知他们任何更改。但是他们总是保持错误的价值。

我的 AppMenuComponent

import { AfterViewInit, Component, OnDestroy, OnInit } from '@angular/core';
import { Subject } from 'rxjs-compat';
import { IndexedDBService } from 'src/app/services/indexeddb.service';

@Component({
  selector: 'app-appmenu',
  templateUrl: './appmenu.component.html',
  styleUrls: ['./appmenu.component.css']
})
export class AppMenuComponent implements OnInit, OnDestroy {

  unsubscribe: Subject<boolean> = new Subject();
  public er: boolean;
  public ew: boolean;
  public eu: boolean;
  public ed: boolean;

  constructor(
    private _indexedDBService: IndexedDBService
  ) {
    this.er = false;
    this.ew = false;
    this.eu = false;
    this.ed = false;
  }

  ngOnDestroy(): void {
    this.unsubscribe.next(true);
    this.unsubscribe.complete();
  }

  ngOnInit(): void {
    this.getUsrPrivileges(); 
  }

  getUsrPrivileges(){
    this._indexedDBService.getER().subscribe(value => this.er = value);
    this._indexedDBService.getEW().subscribe(value => this.ew = value);
    this._indexedDBService.getEU().subscribe(value => this.eu = value);
    this._indexedDBService.getED().subscribe(value => this.ed = value);
  }
}

在我的 AppMenu html 我 show/hide 项目取决于 er 值 ([hidden]="!er"):

...

<!-- Gestionar Alumnos -->
<ul class="nav nav-treeview" [hidden]="!er">
    <li class="nav-item">
        <a [routerLink]="['/alumnos/gestionalumno']" class="nav-link">
            <i class="fas fa-user-graduate"></i>
            <p style="padding-left: 7px;">Alumnos</p>
        </a>
    </li>
</ul>
<!-- Fin Gestionar Alumnos -->

<!-- Gestionar Tutores -->
<ul class="nav nav-treeview" [hidden]="!er">
    <li class="nav-item">
        <a [routerLink]="['/']" class="nav-link">
            <i class="fas fa-user-tie"></i>
            <p style="padding-left: 7px;">Tutores</p>
        </a>
    </li>
</ul>
<!-- Fin Gestionar Tutores -->

<!-- Gestionar Profesores -->
<ul class="nav nav-treeview" [hidden]="!er">
    <li class="nav-item">
        <a [routerLink]="['/']" class="nav-link">
            <i class="fas fa-chalkboard-teacher"></i>
            <p style="padding-left: 7px;">Profesores</p>
        </a>
    </li>
</ul>
<!-- Fin Gestionar Profesores -->

...

我在登录的时候填的权限都是true,但是Alumno, Tutor, Profesor一直都是隐藏的,因为他们没有检测到这个值变成了true;

在我的 indexeddb 中,我看到这些变量的值是真实的。

我怀疑 BehavorSubject 变量在订阅者被订阅之前会发出值。这是可能的?如果是这样...我能做些什么来解决它?

终于找到问题了! 出现这个问题是因为我正在使用不同的 IndxedDBService 实例。

应用程序的所有组件都与 appModule 中提供的 IndexedDBService 一起工作,但不小心我在我的登录组件中添加了这个提供程序。因此,出于这个原因,所有组件都在用一只手工作,而登录组件则用另一只手工作。

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css'],
  providers: [AuthenticationService,IndexedDBService]
})
export class LoginComponent implements OnInit {

因此,删除登录组件提供程序的 IndexedDBService。问题已解决

提供商:[AuthenticationService]