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]
我正在使用异步工作的 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]