2016-09-09 32 views
1

我想要兩個不同的組件和兩個不同的路由,我想將信息從componentA傳遞到componentB。 我做了以下內容:1 - 創建一個處理 2-在componentA設置信息和事件傳遞給服務事件 3-嘗試在以componentBangular2(rc1)Observable not working

我的服務得到這個信息的服務:

@Injectable() 
export class TokenService{ 
private tokenSource = new Subject<Object>(); 
token$ = this.tokenSource.asObservable(); 

setToken(token: string) { 
    this.tokenSource.next(token); 
} 

ComponentA:

@Component({ 
selector: 'login', 
templateUrl: './login.html', 
providers: [TokenService], 
moduleId: module.id 
}) 

export class LoginCmp { 
    constructor(private tokenService: TokenService) { 
} 

someMethod() { 
    this.tokenService.setToken('some dinamyc value'); 
} 
.... 

以componentB:

@Component({ 
selector: 'cabecalho', 
moduleId: module.id, 
templateUrl: './cabecalho.html', 
providers: [TokenService] 
}) 

constructor(private tokenService: TokenService) { 
tokenService.token$.subscribe(
    data => { 
    console.log(data); 

    }); 
} 

當我設置了一些信息,從ComponentA我的控制檯打印,也不要什麼,我把在以componentB與console.log(data)

+0

都是在同一個NgModule組件?嘗試在我們的NgModule中註冊服務,而不是在這兩個組件中使用'providers'數組。 – candidJ

+0

@candidJ RC1沒有NgModule – Gustavo

+0

確實沒有錯誤顯示?我會建議你更新到'rc6' – candidJ

回答

0

首先,您的組件正在使用TokenService的不同實例。您需要在它們之間使用共享服務。

其次,componentB只訂購它被設置在componentA中。如果您在設置值時未訂閱主題,則無法獲得該值。如果您打算在訂閱之前設置該值,則應該使用BehaviourourSubject。訂閱BehaviourSubject將允許您接收設置的最後一個值以及後續值。

第三,使用asObservable意味着你不希望能夠接下來tokenSource的值。然而,你有一個功能可以做到這一點,並可以從componentB訪問。我會建議在單獨的服務中設置tokenSource,它將在ComponentA和tokenService之間共享。

您可以嘗試以下方法。創建共享服務:

@Injectable() 
export class SharedService { 
    tokenSource = new BehaviorSubject<Object>('initial value'); 

    setToken(token: string) { 
     this.tokenSource.next(token); 
    } 
} 

在您的AppComponent bootstrapper函數中初始化SharedService的共享實例。

bootstrap(AppComponent, [ SharedService ]); 

創建一個TokenService。傳SharedService您TokenService的構造函數的實例(DONOT添加SharedService爲[商],因爲它會創建一個新的實例):

@Injectable() 
export class TokenService { 
    token$: any; 
    constructor(sharedService: SharedService) { 
     this.token$ = sharedService.tokenSource.asObservable(); 
    } 

ComponentA(同樣,DONOT在[商]指定SharedService。所以,直到它找到SharedService實例Angular2將搜索最多的層次結構。)

@Component({ 
    selector: 'compA', 
    templateUrl: '/compA.html', 
}) 

export class ComponentA { 
    constructor(private sharedService: SharedService){ 
     console.log('CompA'); 
     this.sharedService.setToken('some dynamic value'); 
    } 
} 

以componentB創建TokenService的新實例。

@Component({ 
    selector: 'compB', 
    templateUrl: '/compB.html', 
    providers: [TokenService] 
}) 

export class ComponentB implements OnDestroy { 
    sub: any; 
    constructor(private tokenService: TokenService) { 
     console.log('CompB'); 
     this.sub = tokenService.token$.subscribe(
      data => { 
       console.log(data); 
      }); 
    } 

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

因此,您有一個共享服務可以公開您的tokenSource值。而一個返回一個可觀察序列的tokenService,因此隱藏了源序列。還有一個組件(B),它可以訂閱這個序列並獲取最後設置的值和後續值,因爲您使用的是BehaviourSubject而不是Subject。

+0

非常感謝你的,現在我明白了我的問題! – Gustavo

0

如果你提供你沒有得到一個共享服務的每個組件上的服務。每個組件都有自己的服務實例。

Angular2爲每個提供者維護一個實例。如果您在共享的父組件上提供服務(最終共享父組件爲AppComponent)或將其傳遞給bootstrap(AppComponent, [TokenService]),則它們將獲得相同的實例注入。

+0

謝謝你,你的解釋是非常重要的 – Gustavo