2017-04-22 85 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解決方案。你的「第一次誤解」在我的情況下是不正確的,我認爲我不承認行爲主體,我知道這個可以變化的東西不會阻止它產生價值......但是你的「第二次誤解」是正確的,並且是我懷疑的解決方案。謝謝。 –