当前位置: 首页 > 知识库问答 >
问题:

行为主题和本地存储

仰翔
2023-03-14

我仍在试图理解rxjs和observables和BehaviorSubject。我想做的是,将BehaviorSubject和LocalStorage结合起来,这样当一个特定的LocalStorage变量发生变化时,所有组件都会得到通知。

例如,考虑以下场景。

>

  • 有两个组件Component1和Component2。

    这两个组件都在Local存储中查找一个名为Component1和Component2的变量,它们包含一种颜色并显示该颜色的正方形。

    Component1 需要订阅 LocalStorage 中的 “Component1Color” 键,Component2 需要订阅 LocalStorage 中的 “Component2Color”。

    实现此目的的一种方法是使用一个维护LocalStorage状态的BehaviorSubject,并在任何变量发生更改时,将此消息广播给订阅了Behavior Subject的所有组件。

    这种方法的问题是,当Component2Color被更新时,component1也会收到通知,而不会对此采取任何措施。

    更好的是,Component1仅在Component1Color更新时得到通知,Component2仅在Component2Color更新时得到通知。有没有一种方法可以用一个单一的行为主体来做到这一点?

  • 共有1个答案

    勾长卿
    2023-03-14

    您可以通过< code>StorageEvent监听存储事件

    const storage = Rx.Observable.fromEvent(window, 'storage').groupBy(ev => ev.key);
    

    然后,您可以通过以下操作访问每个流:

    let component1Stream = storage.filter(x => x.key === 'Component1Color').merge();
    
    //Or using flatMap
    let component2Stream = storage.flatMap(x =>
      x.key === 'Component2Color' ? x : Rx.Observable.empty()
    );
    

    编辑

    正如评论中指出的,存储事件仅对跨页更新有用,如果您在同一页上,它不会更新。幸运的是,解决方案几乎保持不变,您只需要为local存储对象提供一个装饰器对象,以便它可以发出事件。

    class RxLocalStorage {
      private _subject: Rx.Subject<any>;
      private _updates: Observable<any>;
      constructor() {
        this._subject = new Rx.Subject();
        this._updates = this._subject.groupBy(ev => ev.key)
          .share();
      }
      getItem(key) { return this._updates.filter(x => x.key === key).merge(); }
      setItem(key, newValue) {
        const oldValue = localStorage.getItem(key);
        const event = {key, newValue, oldValue};
        localStorage.setItem(newValue);
        this._subject.next(event);
      }
    }
    
    
    let myLocalStorage = new RxLocalStorage();
    myLocalStorage.getItem('Component1Color')
      .subscribe(x => console.log('Component1 Color changed'));
    
    myLocalStorage.setItem('Component1Color', 'blue');
    //-> Component1 Color changed
    

    请注意,以上假设在开始进行更改之前已完成所有订阅。

     类似资料:
    • 如果我不在合适的StackExchange论坛,请建议我在哪里提问: 我在一家公司工作,他编写了处理敏感数据的软件。为了防止软件被复制(软件盗版),很久以前就决定使用许可证制度。 这个系统运行良好,但对我的公司和客户来说都是一个很大的负担,因此我正在寻找其他方法。 我发现的一种方法是SaaS,但我看到了一个巨大的缺点:Saas在互联网上工作,这意味着本地数据被上传到云上(因此是互联网),这让客户感

    • 我一直在寻找了解这 3 个: 主题 行为主体 重播主题 我想使用它们,并知道何时、为什么使用它们,使用它们有什么好处,尽管我已经阅读了文档、观看了教程并搜索了谷歌,但我对此没有任何理解。 那么他们的目的是什么?一个真实的案例将是最受欢迎的,它甚至不需要编写代码。 我更喜欢一个干净的解释,而不仅仅是“a b = 非常感谢。

    • 我们希望侦听特定的Kafka主题,并构建它的“历史”--所以对于指定的键,提取一些数据,将其添加到该键的现有列表中(如果不存在,则创建一个新的列表),并将其放到另一个主题中,该主题只有一个分区,并且高度压缩。另一个应用程序可以只听这个主题并更新它的历史列表。 我在想它如何适合Kafka流库。我们当然可以使用聚合: 它创建一个由Kafka支持的本地存储,并将其用作历史表。 问题是,如果我只是为每个正

    • 我们尝试使用BehaviorSubject跨多个组件共享API数据。在我的组件上,我触发一个HTTP请求,并在返回响应后更新主题。 组件技术 服务台 请求完成后,如何仅访问行为主体的最后发出的值?

    • localStorage 本地存储 存储针对QQ帐号隔离 数据存储于本地文件中。游戏结束后不会被删除 函数 key( index) 获取对应索引的key 手q 版本7.8.5 参数 参数名 类型 说明 index number 索引值 返回值 类型 说明 string 说明 示例 var stringKey = BK.localStorage.key(0); getItem( key) 获取ke

    • 我已经尝试了一切方法来添加本地存储来持久化主题。关于如何使用现有代码实现的任何想法?第一次渲染时,我得到了冲突主题的混合。我尝试在设置主题时实现本地存储。 他们的提供者。js