2017-06-28 1 views
2

Ich habe einen Dienst, der Benutzerobjekte vom Server empfängt. Ich möchte, dass meine Navigationsleiste die "Login" -Schaltfläche versteckt, wenn der Benutzer gespeichert wird (und sie anzeigen, wenn der Benutzer fallengelassen wird). Ich schrieb einen Dienst, der alle der KomponentenAngular 4 BehaviorSubject wird nicht korrekt per Multicast gesendet

indizierten mitteilen sollte

import { Injectable } from '@angular/core'; 
 
import { Observable } from 'rxjs'; 
 
import { Subject } from 'rxjs/Subject'; 
 
import { User } from '../models/user'; 
 
import { BehaviorSubject } from 'rxjs/BehaviorSubject'; 
 
@Injectable() 
 
export class MessageService { 
 

 
    user: User; 
 
    subject = new BehaviorSubject(this.user); 
 

 
    setUser() { 
 
    console.log('setting user...') 
 
    try { 
 
     var user = JSON.parse(localStorage.getItem('currentUser')); 
 
     this.subject.next(user); 
 
     console.log('setted' + JSON.stringify(user)); 
 
    } catch (error) { 
 
     console.log(error); 
 
     this.subject.next(null); 
 
    } 
 

 
    } 
 

 
    unsetUser(){ 
 
    console.log("Current user was' " + this.subject); 
 
    localStorage.removeItem('userToken'); 
 
    localStorage.removeItem('currentUser'); 
 
    this.subject.next(null); 
 
    } 
 

 
}

und die navbar Komponente, die er abonniert

import { Component } from '@angular/core'; 
 
import { User } from '../models/user'; 
 

 
import { Subscription } from 'rxjs/Subscription'; 
 
import { MessageService } from '../services/message.service'; 
 

 
@Component({ 
 
    selector: 'nav-comp', 
 
    templateUrl: './nav.component.html', 
 
    styleUrls: ['./nav.component.css'], 
 
    providers: [ MessageService], 
 
}) 
 
export class NavComponent { 
 

 
    public currentUser: User; 
 
    subscription: Subscription; 
 

 
    constructor(
 
    private messageService: MessageService,) { 
 
    this.subscription = messageService.subject.subscribe({ 
 
     next: (User) => this.currentUser = User }); 
 
    console.log('received: ' + this.currentUser); 
 
    } 
 

 
    quit() { 
 
    console.log("performing logout..."); 
 
    this.messageService.unsetUser(); 
 
    } 
 

 
}
<nav class="white" role="navigation"> 
 
    <div class="nav-wrapper container"> 
 
    <ul class="left hide-on-med-and-down"> 
 
     <li><a routerLink="/home" routerLinkActive="active" id="logo-container" href="#" class="brand-logo">Skoob</a></li> 
 
    </ul> 
 
    <ul class="right hide-on-med-and-down"> 
 
     <li *ngIf="currentUser==null"><a class=" btn-flat" routerLink="/signup" routerLinkActive="active">registrati </a></li> 
 
     <li *ngIf="currentUser==null"><a class=" btn-flat" routerLink="/login" routerLinkActive="active">accedi</a></li> 
 
     <li *ngIf="currentUser!=null"><a class=" btn-flat" (click)="this.quit()" routerLinkActive="active">logout</a></li> 
 
     <li *ngIf="currentUser!=null"><a class="btn-flat">dashboard</a></li> 
 
    </ul> 
 

 
    <ul id="nav-mobile" class="side-nav cyan"> 
 
     <li><a class=" btn">Button <i class="material-icons right">cloud</i></a></li> 
 
    </ul> 
 
    <a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a> 
 
    </div> 
 
</nav>

navbar erhält nur undefiniert, wenn beginnt, aber nichts mehr

UPDATE: wenn ich this.subject.value es überprüfen hat den richtigen Wert, aber navbar nicht weiß ...

Antwort

3

Das Problem ist, dass Sie den Dienst auf Komponentenebene bieten:

@Component({ 
    selector: 'nav-comp', 
    templateUrl: './nav.component.html', 
    styleUrls: ['./nav.component.css'], 
    providers: [ MessageService], // here! 
}) 

Dies bedeutet, dass diese Komponente eine eigene Instanz des Dienstes besitzt. Es ist also kein gemeinsamer Dienst. Aus diesem Grund erhält Ihre Komponente nur den Anfangswert user, also undefined, aber dieser Wert ändert sich nie wieder, da es sich um eine vollständig separate Serviceinstanz handelt.

Um tatsächlich ein Service geteilt wird, müssen Sie den Dienst auf Modulebene zur Verfügung zu stellen:

@NgModule({ 
.... 
providers: [MessageService] 
}) 

und entfernen Sie alle providers Arrays von Komponenten!

Verwandte Themen