2017-02-19 47 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()