组件之间的通信服务不起作用

我正在使用 BehaviorSubject 类来更新全局中的通知数 . 我有2个组件:组件通知显示通知列表,您可以将这些通知设置为已读 . Headers 组件显示未读取的通知数,以便让用户知道他错过了网站上的内容 . 由于有2个不同的组件,我正在使用服务通过它们进行通信 .

这里有一些片段:

notification.service.ts

export class NotificationService {
     public notification: BehaviorSubject<Object> = new BehaviorSubject<Object>({});
     public nbNotificationsChange: BehaviorSubject<number>;

constructor(){
     this.nbNotificationsChange = new BehaviorSubject<number>(0);
}

updateNbNotification(value) {
    this.nbNotificationsChange.next(value);
    this.nbNotificationsChange.subscribe(x => console.log(x));
}

getNbNotification(){
    return this.nbNotificationsChange.getValue();
} }

header.component.ts

export class HeaderComponent implements OnInit, DoCheck {
    public notifications: Notification[] = [];
    public nbNotifications: number = 0;


    constructor (public notificationService: NotificationService){
    this.notificationService.nbNotificationsChange.subscribe(value => {
            this.nbNotifications = value;
        });
    }
ngOnInit() {
    this.getNotificationsNotRead();
    this.notificationService.nbNotificationsChange.subscribe(value => {
        this.nbNotifications = value;
    });
}

ngDoCheck(){
    this.nbNotifications = this.notificationService.getNbNotification()
    //console.log("test");
}
getNotificationsNotRead(){
    aNotRelevantFunctionToRetreiveNotification.subscribe(
            this.notifications = //Receive an array of Notifications here with some code
            this.notifications = this.notifications.filter((notif : Notification) => notif.seen == false); // Check if a notification is read or not
            this.notificationService.updateNbNotification(this.notifications.length);
            console.log(this.notifications.length);
    );
}

get nbNotif(): number {
    return this.notificationService.getNbNotification();
} }

notification.component.ts

export class NotificationsComponent implements OnInit {

public notifications: Notification[];

constructor(public notificationService: NotificationService) {}

ngOnInit() {
    this.getAllNotifications();
}

public getAllNotifications() {
    //Receive an array of notifications to display them, passsing this code. We're in the subscribe
    var nbNotifNotRead = this.notifications.filter((notif : Notification) => notif.seen == false).length;
    this.notificationService.updateNbNotification(nbNotifNotRead); //This value is properly set
}
}

问题是,即使在notification.component.ts一侧设置了值,在header.component.ts中检索的值也不是好的,并且是最初的一个,当然不是我想要的 .

有没有人有想法?现在已经在这个问题上挣扎太久了


更新

这是html部分,非常简单:

<span class="SomeCSSClasses" *ngIf="nbNotifications > 0">{{nbNotifications}}</span>

更新2

该模块涉及:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpModule } from '@angular/http';
/* A lot of imports */

@NgModule({
  imports: [
    CommonModule,
    HttpModule,

  ],
  providers: [
    ApiService,
    CurrencyService,
    /* A lot of services */
    NbNotificationService
    ]
})

export class ServicesModule { }

这是在App.module中导入的原始模块 . 我通过这样创建自己的模块:

import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';

import { NbNotificationService } from './nb-notification.service';
@NgModule({
  providers:    [ NbNotificationService ]
})

export class NbNotificationServiceModule {
    constructor (@Optional() @SkipSelf() parentModule: NbNotificationServiceModule) {
        if (parentModule) {
          throw new Error(
            'NbNotificationServiceModule is already loaded. Import it in the AppModule only');
        }
      }

    static forRoot(): ModuleWithProviders {
        return {
          ngModule: NbNotificationServiceModule,
          providers: [
            {provide: NbNotificationService, useValue: 0 }
          ]
        };
      }
}

试图将此添加到AppModule但它说错误如下: Cannot instantiate cyclic dependency! NbNotificationService ("[ERROR ->]"): in NgModule PagesModule in ./PagesModule@-1:-1

回答(2)

2 years ago

如果您的服务是在延迟加载的模块中提供的,并且您需要应用程序范围的单例,则需要实现 .forRoot() 并在那里提供服务并使用 MyModule.forRoot 导入 AppModule 中的模块 .

由于DI上下文在创建后无法修改,因此延迟加载的模块为其提供者获取新的上下文,并且只有此模块和作为其一部分加载的其他模块才能看到相同的提供者实例 . AppModule ,非延迟加载的模块和其他延迟加载的模块将获得没有或不同的实例 .

另见https://angular.io/guide/singleton-services#forroot

2 years ago

由于您的服务中有通知,为什么不简单地使用getter?

notification.service.ts

notifications: Notification[];

header.component.ts

get totalNotifications() { return this.notificationService.notifications.length; }