rxjs可观测对象在angular 2中用于本地存储的更改。

19 浏览
0 Comments

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日
0
0 Comments

我编写了一个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,只有几个月的经验。欢迎任何改进或建议 🙂 )

0
0 Comments

你想要的是一个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);
  }
...

0