BehaviorSubject变量在注销后保存数据

时间:2018-04-04 18:20:20

标签: angular rxjs

我有一个共享服务如下:

data = new BehaviorSubject<any[]>([]);
constructor(userService: UserService){
  if (localStorage.getItem('data') === null) {
    userService.getAllData().subscribe(results =>

      this.data.next(results)
 }
  else {
    this.loadData()
  }
}

loadData() {
  let data = JSON.parse(localStorage.getItem('data');
  this.data.next(data);
}

setData(data) {
  localStorage.setItem('data', JSON.stringify(data))
  this.data.next(data)
}

然后在ngOnInit()的组件上我有:

ngOnInit() {
  this.sharedService.data.subscribe(results =>
    this.allData = results;
  )
}

itemChange() {
  this.allData.slice(index, 5);
  this.sharedService.data.next(this.allData)
}

和OnLogout我有:

   localStorage.removeItem('data')

问题是在第一页重新加载时,服务被调用,我有预期的数据,我进行更改,然后在我注销后重新登录, 在存储上我不再拥有数据键,但是不再调用sharedService,而是在组件onInit上,this.sharedService.data已经从上次填充。

如何让它每次都调用sharedService,以便检查项目('data')是否存在,就像它在服务构造函数上一样?

3 个答案:

答案 0 :(得分:3)

我想您必须通过发出初始值来重置通过behaviourSubject发出的值。可能不是完美的答案,但我相信它会起作用。

自定义可观察结果背后的原因无法完成,您需要手动进行。

答案 1 :(得分:1)

我建议您重新构建服务。这样做。

您不允许订阅者订阅数据 - BehaviorSubject本身,而是订阅getter方法,而不是将您的对象作为Observable返回。相同的效果,但您现在可以在订阅发生时另外调用其他私有方法。

import { Observable } from 'rxjs/Observable';

private data = new BehaviorSubject<any[]>([]);

constructor(private userService: UserService){}

getData(): Observable<Array<any>> {

    // called once with/by each subscription    
    this.updateData();

    return this.data.asObservable();
}

现在,您可以使用每个新订阅调用私有方法updateData()。此方法将执行您当前在构造函数中执行的检查。但是,这项检查现在不仅会在服务实例化时发生一次,而且每次运行新应用程序时都会关闭浏览器或只是注销。

getDataValue(): Array<any> {
    return this.data.getValue();
}

setData(val: Array<any>) {
    localStorage.setItem('data', JSON.stringify(val));
    this.data.next(val);
}


private updateData(): void {
       const storage = localStorage.getItem('data');

       if (storage === null) {

          this.userService.getAllData().subscribe(results => {
             this.data.next(results);
          }

      } else {
          this.data.next(JSON.parse(storage));
      }
}

在你的组件中:

import { Subscription } from 'rxjs/Rx';

private subscription: Subscription;

ngOnInit() {
   this. subscription = this.sharedService.getData().subscribe(results =>
      this.allData = results;
   )
}

ngOnDestroy() {
    if (this.subscription) {
        this.subscription.unsubscribe();
    }
}

应该这样做。

答案 2 :(得分:0)

扩展组件中的代码。实施订阅,以便在离开/关闭组件时取消订阅服务:

import { Subscription } from 'rxjs/Rx';

private subscription: Subscription;

ngOnInit() {
   this. subscription = this.sharedService.data.subscribe(results =>
      this.allData = results;
   )
}

ngOnDestroy() {
    if (this.subscription) {
        this.subscription.unsubscribe();
    }
}

PS:如果您不想在浏览器的存储中删除对象,请使用 sessionStorage 而不是localStorage。只要关闭当前选项卡或整个浏览器,就会删除sessionStorage中的所有内容。