2017-04-22 88 views
1

我有一个服务注入组件(我的数据存储),从其他http服务提供数据。您可以通过延迟加载路由配置(loadChildren)访问此组件。服务没有被破坏(或刷新,清理......)当不需要

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

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

我知道组​​件可以通过另一种方法从服务中获取新鲜数据,但我认为服务已经应该从Constructor-ngOnInt获取数据。问题是服务没有被破坏,红外线......数据仍然来自旧用户。

这是我的代码。

组件

constructor(
public busquedasStore: BusquedasStore) { } 

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

ngOnDestroy() { 
this.busquedasSubs.unsubscribe(); 
} 

服务

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$; 
} 
+1

服务是单身,它们的生命周期是组件不同。您有一个行为主题,它将以前的值重播给新的订阅者,在这种情况下(直到您触发新的读取)才是之前的用户数据。您应该在用户登录时调用'cargarDatosIni'来获取新数据。 – jonrsharpe

回答

1

我不知道这是否会解决您的特定问题,但被注入是从供应商层次采取喷油器的服务,这样你就可以在NgModule级别注册供应商并/或在Component级别注册供应商。

@Component({ 
    // ... 
    providers: [BusquedasStore] 
    // ... 
}) 
export class MyComponent {} 

这将意味着每个新的组件被创建时它会得到一个服务的新实例(事实上,它会破坏时组件被摧毁了旧的);如果您在那里指定它,它将覆盖当前的NgModuleBusquedasStore服务。

https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html更多信息

+0

是的,这是正确的回应。我认为即使它们在模块级别被注入模块级别 –

+0

@JavierRB,他们在每个模块实例中注入一次(与实际组件相同),但它们被破坏。但是,由于每个应用程序只能有一个模块实例,所以模块不会被破坏=>服务也不会被破坏 – smnbbrv

2

因为在你的代码的项目的名称是在西班牙,我没有更多的情况下,但我可以拿起你在做什么的要点。

您当前的执行

你的服务使用BehaviorSubject约在人登录后当前用户“存储”信息服务检索信息本身创建时。在登录时显示的组件中,您订阅了BehaviorSubject以获取该用户数据,然后在该组件的ngDestroy上取消订阅,因此您希望该服务也将被销毁,以便在登录时与其他人一起,该服务将以新用户的信息重新创建。

误会

不幸的是,你的subscribeunsubscribe理解,当谈到BehaviorSubjects是不准确的,这是(部分),为什么你没有得到你所期望的行为。一个BehaviorSubject可以同时支持许多不同的订阅者,因此,一个订阅者退订它并不会导致它停止生成值(或清除它已经生成的任何现有值)。

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

的解决方案

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

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

所以,

@Injectable() 
export class BusquedasStore { 

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

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

...... 

,并在你的组件,

ngOnInit() { 
this.busquedasStore.cargarDatosIni(); // <--- add your service initialization call 
this.busquedasSubs = this.busquedasStore.busquedas.subscribe(b => { 
    this.busquedas = b; 
}) 
+0

是的,我现在的解决方案是您的secod解决方案。你的“第一次误解”在我的情况下是不正确的,我认为我不承认行为主体,我知道这个可以变化的东西不会阻止它产生价值......但是你的“第二次误解”是正确的,并且是我怀疑的解决方案。谢谢。 –