关于angular:BehaviorSubject变量在注销后保留数据

BehaviorSubject variable keeps data after logout

我有如下共享服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
data = new BehaviorSubject([]);
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()的组件上,我有:

1
2
3
4
5
6
7
8
9
10
ngOnInit() {
  this.sharedService.data.subscribe(results =>
    this.allData = results;
  )
}

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

和OnLogout我有:

1
   localStorage.removeItem('data')

问题是,在第一页重新加载时,服务被调用,并且我得到了预期的数据,进行了更改,然后注销并重新登录后,
在存储中,我不再具有数据键,但是仍然不会再次调用sharedService,相反,在onInit组件上,this.sharedService.data已从上次填充。

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


我建议您然后重组服务。用这种方式做。

您不让订阅服务器订阅data-BehaviorSubject本身,而是订阅一种getter方法,该方法将您的对象作为Observable返回。效果相同,但是现在只要有订阅发生,您就可以另外调用其他私有方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
import { Observable } from 'rxjs/Observable';

private data = new BehaviorSubject([]);

constructor(private userService: UserService){}

getData(): Observable<Array> {

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

    return this.data.asObservable();
}

现在,对于每个新订阅,您都调用私有方法updateData()。此方法将执行您当前在构造函数中执行的检查。但是,现在不仅会在实例化服务时进行一次检查,而且无论关闭浏览器还是直接注销,每次运行新的应用程序时都将进行检查。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
getDataValue(): Array {
    return this.data.getValue();
}

setData(val: Array) {
    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));
      }
}

在您的组件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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();
    }
}

这应该做。


在您的组件中扩展代码。实现订阅,以便在离开/关闭组件后可以取消订阅该服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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中的所有内容都将被删除。