rxjs可观测对象在angular 2中用于本地存储的更改。
rxjs可观测对象在angular 2中用于本地存储的更改。
我正在尝试创建一个可观察对象,当localStorage变量发生更改时返回值。当localStorage(或内存中的变量)更改时,我的订阅者没有获取新的值。
navbar.component.js
import { Component, OnInit } from '@angular/core'; import { UserService } from '../services/user.service'; /** * This class represents the navigation bar component. */ @Component({ moduleId: module.id, selector: 'sd-navbar', templateUrl: 'navbar.component.html', styleUrls: ['navbar.component.css'], providers: [UserService] }) export class NavbarComponent implements OnInit { loggedIn: boolean; constructor(private us: UserService) { } ngOnInit() { this.us.isLoggedIn().subscribe(loggedIn => { this.loggedIn = loggedIn; }); } }
auth.component.ts
import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { UserService } from '../shared/services/user.service'; /** * This class represents the lazy loaded AuthComponent. */ @Component({ moduleId: module.id, selector: 'sd-auth', templateUrl: 'auth.component.html', styleUrls: ['auth.component.css'], providers: [UserService] }) export class AuthComponent implements OnInit { authParams = { provider: '', params: {} }; constructor(private route: ActivatedRoute, private us: UserService) { } ngOnInit() { this.route.params.forEach((param) => { this.authParams.provider = param.authprovider; }); this.route.queryParams.forEach((queryParams) => { this.authParams.params = queryParams; }); this.us.logIn("google", JSON.stringify(this.authParams)); console.log(JSON.parse(localStorage.getItem('authParams'))); } }
user.service.ts
// user.service.ts import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Observable'; import { Subscriber } from 'rxjs/Subscriber'; @Injectable() export class UserService { private loggedIn = false; private logger = new Observable((observer: Subscriber) => { observer.next(this.loggedIn); }); constructor() { if (localStorage.getItem('authParams')) { this.loggedIn = !!JSON.parse(localStorage.getItem('authParams')).params.id_token; } else { this.loggedIn = false; } } logIn(provider: string, providerResponse: string) { localStorage.setItem('authParams', providerResponse); this.loggedIn = true; } isLoggedIn(): Observable { return this.logger; } logOut() { localStorage.removeItem('authParams'); this.loggedIn = false; } }
流程如下:
步骤1- Navbar订阅UserService(获取loggedIn=false的默认值)
步骤2- AuthComponent更新UserService(设置loggedIn = true)
我的Navbar订阅没有更新。我在这里缺少什么。我需要在UserService的logIn方法中放置像事件发射器之类的东西吗?
admin 更改状态以发布 2023年5月21日
我编写了一个StorageService来支持Observable localStorage和sessionStorage。 它支持在一个服务中同时支持这两个存储方式。
\nStorageService
\n
import { BehaviorSubject, Observable } from 'rxjs'; /** * Storage service * used for persist application data in observable key value pair */ export class StorageService { private storage: Storage; private subjects: Map>; /** * Constructor with service injection * @param storage */ constructor(storage: Storage) { this.storage = storage; this.subjects = new Map >(); } /** * watch data of given key * @param key * @param defaultValue */ watch(key: string): Observable { if (!this.subjects.has(key)) { this.subjects.set(key, new BehaviorSubject (null)); } var item = this.storage.getItem(key); if (item === "undefined") { item = undefined; } else { item = JSON.parse(item); } this.subjects.get(key).next(item); return this.subjects.get(key).asObservable(); } /** * get data of given key * @param key */ get(key: string): any { var item = this.storage.getItem(key); if (item === "undefined") { item = undefined; } else { item = JSON.parse(item); } return item; } /** * set value on given key * @param key * @param value */ set(key: string, value: any) { this.storage.setItem(key, JSON.stringify(value)); if (!this.subjects.has(key)) { this.subjects.set(key, new BehaviorSubject (value)); } else { this.subjects.get(key).next(value); } } /** * remove given key * @param key */ remove(key: string) { if (this.subjects.has(key)) { this.subjects.get(key).complete(); this.subjects.delete(key); } this.storage.removeItem(key); } /** * clear all available keys */ clear() { this.subjects.clear(); this.storage.clear(); } }
\nLocalStorageService
\n
import { Injectable, Inject } from '@angular/core'; import { StorageService } from './storage.service'; /** * Local storage service * used for persist application data in observable key value pair */ @Injectable() export class LocalStorageService extends StorageService { /** * Constructor with service injection * @param window */ constructor(@Inject('WINDOW') private window: any) { super(window.localStorage); } }
\nSessionStorageService
\n
import { Injectable, Inject } from '@angular/core'; import { StorageService } from './storage.service'; /** * Session storage service * used for persist application data in observable key value pair */ @Injectable() export class SessionStorageService extends StorageService { /** * Constructor with service injection * @param window */ constructor(@Inject('WINDOW') private window: any) { super(window.sessionStorage); } }
\n这是您可以使用服务的方式:
\n
import { LocalStorageService } from './local-storage.service'; export class TestClass implements OnInit, OnDestroy { constructor( private localStorage: LocalStorageService, ) { } ngOnInit() { // get current value this.localStorage.get('foo'); // set new value this.localStorage.set('foo', 'bar'); // watch value changes this.localStorage.watch('foo').pipe(takeUntil(this.unsubscribe)).subscribe(foo => console.log('foo changed', foo)); } ngOnDestroy() { this.unsubscribe.next(); this.unsubscribe.complete(); } }
\n(我真的很新于TypeScript,只有几个月的经验。欢迎任何改进或建议 🙂 )
你想要的是一个Subject。在这里查看文档。对于一个快速的例子,可以用类似下面的东西:
export class UserService { ... private logger = new Subject(); ... isLoggedIn(): Observable { return this.logger.asObservable(); } logIn(provider: string, providerResponse: string) { localStorage.setItem('authParams', providerResponse); this.loggedIn = true; this.logger.next(this.loggedIn); } logOut() { localStorage.removeItem('authParams'); this.loggedIn = false; this.logger.next(this.loggedIn); } ...
。