2017-02-19 68 views
0

我有一個發送事件的身份驗證服務。當用戶登錄時(通過LoginComponent),必須更新導航欄(NavBarComponent)。這些組件是在同一水平Angular 2 - 從服務到同級組件的事件

首先我嘗試使用EventEmitter,然後我讀我們不應該在服務中使用它。這是一種反模式。

所以,我想https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

auth.service.ts

import {Injectable}  from '@angular/core'; 
import { Subject } from 'rxjs/Subject'; 

@Injectable() 
export class AuthService { 

    private connectionState: boolean; 
    private stateChangeSource = new Subject<boolean>(); 
    // Observable boolean stream 
    stateChange$ = this.stateChangeSource.asObservable(); 

    constructor(private http: Http) { 
    } 

    changeConnectionState() { 
    this.stateChangeSource.next(!this.connectionState); 
    } 
} 

login.component.ts

import {Component, Inject} from '@angular/core'; 
import {AuthService} from './auth.service'; 

@Component({ 
    selector: 'login-component', 
    templateUrl: './login.component.html' 
}) 
export class LoginComponent { 

    constructor(private authService: AuthService) { 
    this.authService = authService; 
    } 

    login() { 
    this.authService.changeConnectionState(); 
    } 
} 

navbar.component.ts

import {Component} from '@angular/core'; 
import {AuthService} from './auth.service'; 

@Component({ 
    selector: 'navbar', 
    templateUrl: './navbar.component.html', 
    providers: [AuthService] 
}) 
export class NavbarComponent { 

    authService: AuthService; 
    connectionState: boolean; 
    subscription: any; 

    constructor(private authService: AuthService) { 
    this.authService = authService; 
    this.subscription = authService.stateChange$.subscribe(
     value => { 
     this.connectionState = value; 
     }) 
    } 

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

navbar.component.html

<nav class="navbar navbar-default navbar-fixed-top"> 
... 
    <a *ngIf="!connectionState" [routerLink]="['/login']">Connect</a> 
    <a *ngIf="connectionState" (click)="disconnect()">Disconnect</a> 
...  
</nav> 

當我打電話

this.authService.changeConnectionState();

from NavbarComponent,navbar已正確更新。 但我想更改loginComponent的連接狀態,然後更新導航欄。我能怎麼做 ?

enter image description here

編輯

事件是NavBarComponent收到:

this.subscription = authService.stateChange$.subscribe(
     value => { 
     this.connectionState = value; 
     }) 

,但其值不更新的模板。我必須更改路由才能獲得正確的「連接狀態」值

+2

如果這些組件處於相同級別並且在其中一個組件上提供,則應該在另一個組件上收到錯誤消息,表明沒有該服務的提供者。 –

+0

你可以嘗試在Plunker中重現嗎? Plunker爲Angular2 TS提供了一個模板。 –

+0

thx爲您的答案。我不能在一個Plunker中重現,我不會面臨同樣的問題。我從NavBarComponent中刪除了「提供者:[AuthService]」,並且有一個改進:「connectionState」的值被改變了,但我必須改變路由才能看到它的修改 – isy

回答

0

我不得不刪除

提供商:[AuthService]

來自Navbar.component.ts

它已經設置在我的app.module.ts

@NgModule({ 
    imports: [ 
    BrowserModule 
    ], 
    declarations: [ 
    LoginComponent 
    ], 
    providers: [ 
    AuthService 
    ], 
    bootstrap: [AppComponent] 
}) 
export class AppModule { 
} 

我有另一個錯誤,由於我的異步調用登錄(不詳細在這篇文章中),我不知道爲什麼。但這不是主題。

1

如果組件處於相同級別,則無法在其中一個組件之間共享它們之間的服務。

你需要在一個共同的祖先組件提供共享服務,或一種非延遲加載@NgModule()