Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ionic framework 行为主体和本地存储_Ionic Framework_Angular_Rxjs_Behaviorsubject - Fatal编程技术网

Ionic framework 行为主体和本地存储

Ionic framework 行为主体和本地存储,ionic-framework,angular,rxjs,behaviorsubject,Ionic Framework,Angular,Rxjs,Behaviorsubject,我仍在试图将我的头脑集中在RXJ、观察对象和行为主体上。我想做的是,将BehaviorSubject和LocalStorage结合起来,以便在特定LocalStorage变量更改时通知所有组件 例如,考虑下面的场景。 有两个组件:组件1和组件2 这两个组件都在LocalStorage中查找一个名为Component1和Component2的变量,该变量包含一种颜色,并且它们显示该颜色的正方形 Component1需要订阅LocalStorage中的“Component1Color”键,Com

我仍在试图将我的头脑集中在RXJ、观察对象和行为主体上。我想做的是,将BehaviorSubject和LocalStorage结合起来,以便在特定LocalStorage变量更改时通知所有组件

例如,考虑下面的场景。

  • 有两个组件:组件1和组件2

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

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

一种方法是让一个BehaviorSubject维护LocalStorage的状态,并且在对任何变量进行更改时,将此消息广播给订阅了BehaviorSubject的所有组件

这种方法的问题是,当Component2Color被更新时,component1也会得到通知,并且不会对此做任何事情


最好的是,只有当Component1Color更新时才会通知Component1,而只有当Component2Color更新时才会通知Component2。是否有一种方法可以使用单个行为子对象完成此操作?

您可以通过

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

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对象提供一个decorator对象,以便它能够发出事件

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
类RxLocalStorage{
私人受试者:接收受试者;
私有更新:可观察;
构造函数(){
此._subject=new Rx.subject();
this.\u updates=this.\u subject.groupBy(ev=>ev.key)
.share();
}
getItem(key){返回此值。_更新.filter(x=>x.key==key.merge();}
setItem(键,newValue){
const oldValue=localStorage.getItem(键);
const event={key,newValue,oldValue};
localStorage.setItem(newValue);
本次.\u主题下一次(活动);
}
}
让myLocalStorage=new RxLocalStorage();
myLocalStorage.getItem('Component1Color')
.subscribe(x=>console.log('Component1变色');
setItem('Component1Color','blue');
//->组件1颜色已更改

注意:以上假设您的所有订阅都是在开始进行更改之前完成的。

您是否使用了
distinctUntilChanged()
?你能发布你的代码,让我们看看你在做什么吗?我只是在玩rxjs,还没有一个有效的代码。我试图弄清楚如何在LocalStorage周围创建一个包装器来处理上述场景。我只是查看了distinctUntilChanged,看起来这正是我想要的:)我可以为每个组件传入一个比较器函数,只有当diff函数成功时才会触发订阅者。此事件仅在未激活的页面中触发。假设有两个选项卡打开到example.com,如果设置了该事件并更新了
tab2
中的存储,则
tab1
将触发该事件,但不会触发
tab2
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