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å.

Relaterte artikler