3

我想创建登录表单,当登录成功时,根组件接收数据然后显示它。我创建了登录服务,根组件可以通过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; 
} 

回答

2

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

将其添加到@NgModule()的供应商,而这样,所有组件都将获得相同的实例注入。

+0

你救了我的一天,非常感谢你。 – Einsamer

+0

不客气。 DI开始从具有依赖关系的组件(构造函数参数)中搜索提供程序,并继续查找其父项,直到找到匹配的提供程序。 DI为每个提供者维护单个实例。如果您将提供程序添加到'@NgModule()',那么它们将被添加到与整个应用程序共享的根注入器中。 –

+0

您也可以通过将组件添加到应用程序的子树来定义提供程序。对于使用根注射器的小型应用程序通常是安全的,对于较大的应用程序或更具体的用例,您可能需要通过向组件添加提供程序来实现更细致的控制。 –