不必要时,服务不会被破坏(或刷新、清理......)

Jav*_* RB 3 dependency-injection angular2-observables angular

我有一个注入了服务的组件(我的数据存储),它从其他 http 服务提供数据。您可以通过延迟加载路由配置(loadChildren)来访问该组件。

当用户注销(到另一个不同的路线)并立即使用不同的用户登录(一个人可以维护两个用户)时,商店服务之前(旧用户)提供相同的数据,当我认为它应该收取新数据时(新用户)。

我认为当用户注销时,服务应该被“销毁”,因为服务观察者被销毁(在 ngOnDestroy 中),并且不需要以再次构建服务的方式进行注入。

我知道该组件可以使用另一种方法从服务获取新的数据,但我认为该服务已经应该从 Constructor-ngOnInt 获取数据。问题是服务没有被破坏、清除......并且数据仍然来自旧用户。

这是我的代码。

成分

constructor(
public busquedasStore: BusquedasStore) { }

ngOnInit() {
 this.busquedasSubs = this.busquedasStore.busquedas.subscribe(b => {
   this.busquedas = b;
})

ngOnDestroy() {
 this.busquedasSubs.unsubscribe();
}
Run Code Online (Sandbox Code Playgroud)

服务

import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Observable";
import { BehaviorSubject } from "rxjs/BehaviorSubject";
import { UserService } from '../../core/user.service';

@Injectable()
export class BusquedasStore {

busquedas$: BehaviorSubject<{}[]> = new BehaviorSubject([]);

constructor(
 public userService:UserService
)  {
 this.cargarDatosIni();
}

cargarDatosIni() {
 this.userService.me().subscribe((res) => {
   let busquedas:{}[] = res.user.busqueda;
   this.busquedas$.next(busquedas);
 },err => {
   console.log(err);
 });
}

get busquedas(): Observable<{}[]> {
 return this.busquedas$;
}
Run Code Online (Sandbox Code Playgroud)

sno*_*ete 5

由于代码中的项目名称是西班牙语,因此我没有其他上下文,但我可以了解您正在做的事情的要点。

您当前的实施

您的服务使用BehaviorSubject 在用户登录后“存储”有关当前用户的信息。服务在创建时会自行检索该信息。在您登录时显示的组件中,您订阅该BehaviorSubject以获取该用户数据,然后您取消订阅该组件的ngDestroy,因此您预计该服务也会被销毁,以便当您登录时对于其他人,将使用新用户的信息重新创建服务。

误会

subscribe不幸的是,您对BehaviorSubjects的理解unsubscribe是不准确的,这(部分)是您没有得到您期望的行为的原因。一个BehaviorSubject可以同时支持许多不同的订阅者,因此,一个订阅者取消订阅它不会导致它停止产生值(或清除它已经产生的任何现有值)。

另一个误解是关于服务如何创建和销毁的。如果服务由 NgModule 提供,则该服务只会创建一次,之后不会重新初始化。但是,如果您在组件级别提供服务,则该服务将共享提供它的组件的生命周期,并且将与组件同时创建和销毁。

解决方案

您有两个基本选择。最快的实施方式可能是仅在组件级别提供服务。因此,如果您的服务在 NgModule 级别有提供程序配置,请将其删除,然后仅将其添加到您的组件中。

第二个选项(我认为可能是更好的长期选项)是更改您的服务,以便它不会在其构造函数中获取用户信息,而是让组件进行该调用。这样,每当新用户登录时,都会进行新的调用来获取用户信息,并且服务将始终反映当前用户的信息。

所以,

@Injectable()
export class BusquedasStore {

busquedas$: BehaviorSubject<{}[]> = new BehaviorSubject([]);

constructor(
 public userService:UserService
)  {
 //this.cargarDatosIni();  <-- remove this line
}

......
Run Code Online (Sandbox Code Playgroud)

在你的组件中,

ngOnInit() {
 this.busquedasStore.cargarDatosIni();   // <--- add your service initialization call
 this.busquedasSubs = this.busquedasStore.busquedas.subscribe(b => {
   this.busquedas = b;
})
Run Code Online (Sandbox Code Playgroud)