Почему код внутри функции подписки выполняется несколько раз - PullRequest
0 голосов
/ 24 января 2019

Я создал службу уведомлений для своего приложения следующим образом:

export class NotificationService {
  private subject = new Subject<Notification>();

  constructor() {}

  getNotification(): Observable<any>{
    return this.subject.asObservable();
  }

  success(title: string, message: string){
    this.notif(NotificationType.SUCCESS, title, message);
  }

  error(title: string, message: string){
    this.notif(NotificationType.ERROR, title, message);
  }

  technicalError(title:string, message: string){
    this.notif(NotificationType.TECHNICAL_ERROR, title, message);
  }

  info(title: string, message: string){
    this.notif(NotificationType.INFO, title, message);
  }

  warning(title: string, message: string){
    this.notif(NotificationType.WARNING, title, message);
  }

  notif(type: NotificationType, title: string, message: string){
    this.subject.next(<Notification>{ type: type, title: title, message: message});
  }

И это пример того, как я использую этот сервис:

this.notificationService.success("Suppression", "L'enregistrement a été supprimée !");

И так как у меня есть компонент, который является общим для всех моих компонентов, который является заголовком, у меня есть подписка на тему службы уведомлений в ее функции ngOnInit:

this.notificationService.getNotification().subscribe((notification: Notification) => {
      this.notification.create(NotificationType[notification.type], notification.title, notification.message);
    });

При первом запуске приложения код внутри функции подписки выполняется один раз, когда я вызываю некоторую функцию уведомлений, но после этого код внутри функции подписки выполняется несколько раз.

Как я могу решить это?

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Каждый раз, когда создается экземпляр вашего компонента заголовка, он создает новую подписку на вашу службу уведомлений. Когда компонент заголовка уничтожен, он должен очистить свои подписки. Если нет, блок подписки будет продолжать выполняться всякий раз, когда наблюдаемое излучает новое значение.

Как правило, любой компонент, подписывающийся на службу, должен содержать метод жизненного цикла ngOnDestroy, который очищает все подписки, которые он сделал.

Чтобы автоматически отписаться, вы можете использовать componentDestroyed Тема вместе с оператором rxjs takeUntil. В ngOnDestroy вы отправляете значение componentDestroyed, которое завершает подписку:

export class HeaderComponent implements OnInit, OnDestroy {
  private componentDestroyed = new Subject<any>();

  constructor(private notificationService: NotificationService) { }

  ngOnInit() {
    this.notificationService.getNotification()
      .pipe(takeUntil(this.componentDestroyed))
      .subscribe(notification => {
        // ...
      });
  }

  ngOnDestroy() {
    this.componentDestroyed.next();
  }
}

Вот пример StackBlitz.

0 голосов
/ 24 января 2019

Вы вызываете метод notif из других методов, таких как success, error, info, warning и т. Д. Метод notif вызывает next для вашего Subject, который в конечном итогевыдвигает новое значение в Subject, которое вы выставили как Observable, вызывая для него метод asObservable().

Убедитесь, что вы не вызываете success, error, info, warning и т. Д. Где-либо еще в вашем приложении.Если эти методы вызываются более одного раза, метод subscribe также будет вызываться более одного раза.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...