typescript - Observable.subscribe-metoden utløses ikke når BehaviorSubject.next kalles
Jeg prøver å finne ut om brukeren er logget inn eller ikke i mitt Navbar-komponent slik at jeg kan aktivere/deaktivere Navbar-elementer. Jeg bruker BehaviorSubject for å multikaste dataene. Min AuthenticationService holder BehaviorSubject-objektet, som du kan se i følgende kode:
import {Injectable} from '@angular/core';
import {Http, RequestOptions, Headers} from '@angular/http';
import {LocalStorage, SessionStorage} from "angular2-localstorage/WebStorage";
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Credentials} from './credentials';
@Injectable()
export class AuthenticationService {
private _baseUrl="http://localhost:8080/webapi/authenticate/";
private loggedIn: boolean;
// Observable UserLoggedIn source
private _userLoggedInBehavior = new BehaviorSubject<boolean>(false);
// Observable UserLoggedIn stream
userLoggedInBehaviorStream = this._userLoggedInBehavior.asObservable();
constructor(private _http: Http){
this.loggedIn = localStorage.getItem("authToken");
}
authenticate(credentials: Credentials){
return this._http.post(
this._baseUrl
, JSON.stringify(credentials)
, this.getOptions()
)
.map(res => res.json())
.map((res) => {
if (res.success) {
sessionStorage.setItem("authToken", res.data.token);
this.loggedIn = true;
}
return res.success;
});
}
logout() {
sessionStorage.removeItem("authToken");
this.loggedIn = false;
}
isLoggedIn() {
return this.loggedIn;
}
changeUserLoggedInBehavior(loggedIn) {
this._userLoggedInBehavior.next(loggedIn);
}
// This was necessary because api accepts only JSON
// and if we do not put this header in requests API
// responds with 415 wrong media object.
getOptions(){
var jsonHeader = new Headers({
'Content-Type':'application/json'
});
var options = new RequestOptions({
headers: jsonHeader
});
return options;
}
}
Min AuthenticationComponent-kode som utløser koden ser slik ut:
import {Component, OnInit, EventEmitter} from '@angular/core';
import {CanDeactivate, Router} from '@angular/router-deprecated';
import {ControlGroup, Control, Validators, FormBuilder} from '@angular/common';
import {AuthenticationService} from './authentication.service';
import {Credentials} from './credentials';
import {EmailValidator} from '../../validators/email-validator';
@Component({
selector:'auth'
, templateUrl:'app/components/authentication/authentication.component.html'
, providers:[AuthenticationService]
})
export class AuthenticationComponent{
form: ControlGroup;
title: string = "LogIn";
credentials: Credentials = new Credentials();
constructor(
fb: FormBuilder
, private _authService: AuthenticationService
, private _router: Router){
this.form = fb.group({
emailId:[
''
, Validators.compose(
[
Validators.required
, EmailValidator.mustBeValidEmail
]
)
]
,password:[
''
, Validators.compose(
[
Validators.required
]
)
]
});
}
save(){
this._authService.authenticate (this.credentials)
.subscribe((result) => {
if (result) {
this._authService.changeUserLoggedInBehavior(true);
this._router.navigate(['Home']);
}
});
}
}
Sist, min NavbarComponent er som følger:
import {Component, OnInit, OnDestroy} from '@angular/core';
import {RouterLink} from '@angular/router-deprecated';
import {Subscription} from 'rxjs/Subscription';
import {AuthenticationService} from '../components/authentication/authentication.service';
@Component({
selector:'navbar'
, templateUrl: 'app/navbar/navbar.component.html'
, directives:[RouterLink]
, providers:[AuthenticationService]
})
export class NavbarComponent implements OnInit, OnDestroy{
private _isUserLoggedIn: boolean=false;
subscription: Subscription;
constructor(
private _authService: AuthenticationService
){}
ngOnInit(){
this.subscription = this._authService.userLoggedInBehaviorStream
.subscribe(
loggedIn => this._isUserLoggedIn = loggedIn
);
}
ngOnDestroy(){
// prevent memory leak when component is destroyed
this.subscription.unsubscribe();
}
public setUserLoggedId (isLoggedIn: boolean){
this._isUserLoggedIn = isLoggedIn;
}
}
Jeg har brukt dette som et eksempel for å skrive koden. Vennligst gi meg beskjed om hvor jeg tar feil.
Svar #1
Problemet er at i begge komponentene dine spesifiserer du provider:
providers:[AuthenticationService]
Hver gang du gir en komponent en tjeneste, vil den få en ny instans. Prøv å gi AuthenticationService i en overordnet komponent og bare injiser i barnekomponenter eller på oppstartsnivå.
