通过服务可观察到的失败在组件之间进行通信

Communicate between component via service observable fail

我想创建登录表单,当登录成功时,根组件接收数据然后显示它。我创建了登录服务,根组件可以使用 subscribe() 方法接收通知,但它似乎不起作用。 这是我的代码:

//app.component.ts
import { Component } from '@angular/core';
import { Router } from '@angular/router';

import { HttpConstant } from './constants/http.response';
import { LoginService } from './services/login.service';

@Component({
    moduleId: module.id,
    selector: 'app',
    templateUrl: 'app.component.html',
    providers: [LoginService]
})

export class AppComponent {
  currentUser = 'Anonymous';

  constructor(private loginService: LoginService) {
      console.log(loginService);
      loginService.logInAnnouncement$.subscribe(email => {
          console.log(email);
          this.currentUser = email;
      });
  }
}
//login.service.ts
import { Injectable } from '@angular/core';
import { Headers, Http, Response } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { Observable } from 'rxjs';
import { Subject }    from 'rxjs/Subject';

import { Profile } from '../entities/profile';
import { GuardService } from './guard.service';

@Injectable()
export class LoginService {

    private headers = new Headers();
    private loginUrl = 'api/v1/auth/login';
    private email = new Subject<string>();

    /**
    * Observable string streams
    */
    logInAnnouncement$ = this.email.asObservable();

    constructor(private http: Http, private guard: GuardService) {
    }

    login(email, password): Observable<any> {
        this.headers.append('Content-Type', 'application/json');
        this.headers.append('Accept', 'application/json');
        return this.http
          .post(this.loginUrl, JSON.stringify({email: email, password: password}), {headers: this.headers})
          .map((res:Response) => res.json());
    }

    announceLogIn(email: string) {
        this.email.next(email);
        this.logInAnnouncement$.subscribe(email=>{
            console.log(email);
        });
        console.log('OK');
    }
}
//login.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { LoginService } from '../services/login.service';
import { Profile } from '../entities/profile';
import { HttpConstant } from '../constants/http.response';


@Component({
    moduleId: module.id,
    selector: 'fix-login',
    templateUrl: 'login.component.html',
    providers: [LoginService, HttpConstant],
})

export class LoginComponent implements OnInit {

    profile: Profile;
    validatingHandler: ValidateError;
    // profile: Profile;

    constructor(private loginService: LoginService,
                 private router: Router) { 
        this.profile = new Profile();
        this.validatingHandler = new ValidateError();
    }

    ngOnInit(): void {

    }

    doLogin(event): void {
        event.preventDefault();
        this.loginService.login(this.profile.email, this.profile.password)
            .subscribe((data: Object) => {
                if (data.status == 0) {
                    this.loginService.announceLogIn(this.profile.email);
                    this.router.navigate(['/']);
                }
            }, err => { 

                if (err.status == HttpConstant.HTTP_INVALID_INPUT ) {
                    this.validatingError(err.json());
                }
            })

    }

    private validatingError(error): void {
        this.validatingHandler = new ValidateError();
        this.validatingHandler._email = error.email;
        this.validatingHandler._password = error.password;
    }


}

class ValidateError {
    _email: string;
    _password: string;
}

不要将 LoginService 添加到每个组件的 providers。这样每个组件都会注入自己的实例。

改为将其添加到 @NgModule() 的提供者,这样所有组件都将注入相同的实例。