使用Angular2中的事件发射器在服务和组件之间共享数据

时间:2017-05-17 10:36:17

标签: angular angular2-services eventemitter

我有一个angular2应用程序,其中有一个登录页面。登录后,我想在标题组件中显示用户名。

    @Output() getUserName = new EventEmitter();

在身份验证方法中

authenticate(loginRequest)  {
    let headers = new Headers({ 'Content-Type' : 'application/json' });
    let options = new RequestOptions({ headers: headers });
    let authenticateResp = this.http.post("http://localhost:8080/authenticate", JSON.stringify(loginRequest), options).map(result => result.json());
    authenticateResp.subscribe((authenticate => {
        this.getUserName.emit("My Name");
    }));    

    return authenticateResp; 
}

在构造函数的头部组件中

@Component({
 .....
 providers:[LoginService]
})
export class HeaderComponent {
  userName : string;
  constructor(private loginService : LoginService) { 

      loginService.getUserName.subscribe(authenticated => this.setName(authenticated));
  }

  setName(authenticated) {
    this.userName = authenticated;
  }

}

当我调试时,我可以看到事件发出代码被执行,但是组件中的订阅中的代码没有被调用。我在这里做错了什么?

感谢任何帮助

1 个答案:

答案 0 :(得分:4)

@Output()EventEmitter并不打算在服务中使用,因为它们是designed for inter-component communication

EventEmitter(现在)Subject的子类,标准Subject,不会将最新的值保留在内存中,所以如果在没有值的情况下发出值订阅者,价值被忽略了。

ReplaySubject会将最后一次发射的值重复到任何新订阅者。

备注

  • 最好只展示Observable而不是Subject
  • 您不希望在authenticateResp方法中订阅authenticate并同时返回authenticateResp,因为如果您订阅了返回的值,则会触发请求两次。您应该使用do()运算符,返回observable并订阅您需要该数据的位置。
private _userName = new ReplaySubject<string>();

userName=this._userName.asObservable();

authenticate(loginRequest)  {
    let headers = new Headers({ 'Content-Type' : 'application/json' });
    let options = new RequestOptions({ headers: headers });
    return this.http.post("http://localhost:8080/authenticate", JSON.stringify(loginRequest), options)
        .map(result => result.json())
        .do((authenticate => this._userName.next("My Name")));    
}

并在您的组件内:

loginService.userName.subscribe(authenticated => this.setName(authenticated));