简体   繁体   English

Angular 4 BehaviorSubject无法正确多播

[英]Angular 4 BehaviorSubject doesn't multicast properly

I have a service who save user object received from the server. 我有一项服务,可以保存从服务器收到的用户对象。 I want my navbar hide the "login" button when user is stored (and show it when user is dropped). 我希望我的导航栏在存储用户时隐藏“登录”按钮(并在删除用户时显示它)。 I wrote a service which should notify all the component subscripted 我编写了一项服务,该服务应通知所有使用下标的组件

 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); } } 

and the navbar component who subscribes to him 以及订阅他的导航栏组件

 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 receives only undefined, when starts, but nothing more 导航栏在启动时仅收到未定义的信息,仅此而已

UPDATE: if i check this.subject.value it has the correct value, but navbar doesn't know ... 更新:如果我检查this.subject.value它具有正确的值,但导航栏不知道...

The issue is, that you are providing the service at component level: 问题是,您正在组件级别提供服务:

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

This means that this component has it's own instance of the service. 这意味着该组件具有其自己的服务实例。 So it's not a shared service at all. 因此,它根本不是共享服务。 That is why your component only gets the initial value of user , which is undefined , but that value never changes again, since this is a totally separate service instance. 这就是为什么您的组件仅获得user的初始值( undefined ,但是该值再也不会更改,因为这是一个完全独立的服务实例。

To actually have a shared service, you need to provide the service at module level: 要真正拥有共享服务,您需要在模块级别提供服务:

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

and remove all providers arrays from components! 并从组件中删除所有providers阵列!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM