我仍在尝试围绕 rxjs 和 observables 以及 BehaviourSubject 进行思考。我想做的是,将BehaviorSubject 和LocalStorage 结合起来,以便在特定LocalStorage 变量发生更改时所有组件都能收到通知。
例如,考虑以下场景。
有两个组件 Component1 和 Component2。
这两个组件都会在 LocalStorage 中查找名为 Component1 和 Component2 的变量,其中包含一种颜色,并显示该颜色的正方形。
Component1需要订阅LocalStorage中的“Component1Color”键,Component2需要订阅LocalStorage中的“Component2Color”键。
实现此目的的一种方法是使用一个BehaviorSubject来维护LocalStorage的状态,并且每当对任何变量进行更改时,都会将此消息广播到所有订阅了BehaviorSubject的组件。
这种方法的问题是,当 Component2Color 更新时,Component1 也会收到通知,但不会对此执行任何操作。
更好的是,Component1 仅在 Component1Color 更新时收到通知,而 Component2 仅在 Component2Color 更新时收到通知。有没有办法使用单个BehaviorSubject 来完成此操作?
最佳答案
您可以通过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()
);
编辑
正如评论中所指出的,存储事件仅对跨页面更新有用,如果您位于同一页面上,则不会更新。幸运的是,解决方案几乎保持不变,您只需要为 localStorage 对象提供一个装饰器对象,以便它可以发出事件。
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
请注意,上述内容假设您的所有订阅都是在您开始进行更改之前进行的。
关于ionic-framework - 行为主体和本地存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38260773/