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

您也可以通過將組件添加到應用程序的子樹來定義提供程序。對於使用根注射器的小型應用程序通常是安全的,對於較大的應用程序或更具體的用例,您可能需要通過向組件添加提供程序來實現更細緻的控制。 –