Angular 6 подписка вызывается несколько раз - PullRequest
0 голосов
/ 07 сентября 2018

Я просто работаю над новым Angular 6 WebApp, в котором вся связь между компонентами основана на Темах и Подписках.

Вся подписка реализована в компоненте панели мониторинга (уровень 1 под корнем). На информационной панели компонент представляет собой таблицу, созданную из базового серверного ядра C # ASP.NET с веб-сокетами SignalR.

Теперь мы реализовали кнопки редактирования и удаления для каждой строки в этой таблице. Кнопка редактирования открывает модал ngx-bootstrap. Модальная функция открытия принимает один параметр в параметре.

Внутри этого "мод-редактирования" есть некоторые входные данные с датой строки. Теперь, когда я сохраняю изменения, данные отправляются обратно в компонент панели мониторинга, который вызывает метод обновления строки с помощью .NET Core API.

Во время этого потока данных между модом редактирования и приборной панелью моя подписка вызывается 4 раза.

Я пытался отладить это, но не могу понять, что здесь происходит ...

Мой сервис для общения:

export class CommunicationService {

  private subject = new Subject<any>();

  constructor() { }

  sendData(data: any) {
    this.subject.next({ data });
  }

  removeData() {
    this.subject.next();
  }

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

}

Редактировать модал:

sendOrderToDashboard(): void {
    // this.order is a data of singel row. Its a table with different user orders as a row.
    this.communicationService.sendData(this.order);
    this.modalRef.hide();
  }

Компонент приборной панели

public ngOnInit(): void {
    this.communicationService.getData().subscribe(orderToUpdate => {
      if (orderToUpdate) {
        this.updateOrder(orderToUpdate.data);
        console.log(orderToUpdate.data);
        // this log invokes 4x times
      }
    });
  }

updateOrder(order): void {
    this.orderService.updateOrder(order).subscribe(next => {
      console.log('updated successfully');
      // This log is never executed even when the update is successful
    }, error => {
      console.log('error while updating order');
    });
  }

Обновление порядка в OrderService (Мост между Angular и SignalR (Backend))

  public updateOrder(order: Order): Observable<Order> {
    if (!this.orderSubjects[order.id]) {
      this.orderSubjects[order.id] = new Subject<Order>();
    }

    this.hubService.invoke(ServerMethod.UpdateOrder, order);

    return this.orderSubjects[order.id].asObservable();
  }

Кто-нибудь знает, почему мой журнал успеха никогда не выполнялся и мой вызывается 4 раза?

Ответы [ 3 ]

0 голосов
/ 07 сентября 2018

В целях отладки я добавил еще несколько журналов в свой компонент Dashboard. Я добавил unsubscribe() к своей подписке в ngOnDestroy(), но этот метод никогда не выполнялся.

updateOrder(order): void {
    console.log('update method is called')
    this.subscription = this.orderService.updateOrder(order).subscribe(next => {
      console.log('updated successfully');
    }, error => {
      console.log('error while updating order');
    });
  }

  public ngOnInit(): void {
    console.log('data is available now');
    this.communicationService.getData().subscribe(orderToUpdate => {
      if (orderToUpdate) {
        this.updateOrder(orderToUpdate.data);
        console.log('update init');
        console.log(orderToUpdate.data);
      }
    });
  }

  public ngOnDestroy(): void {
    if (this.subscription) {
      this.subscription.unsubscribe();
      console.log('successfuly unsubscribe');
    }
  }

Кажется, что весь компонент инициализируется 2 раза? И отписаться никогда не будет выполнено. Я добавил скриншот ниже с console.log

Журналы консоли

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

В вашем компоненте Dashboard я не вижу выражения класса экспорта, проверьте, что вы реализовали OnDestroy.

Ваш класс должен выглядеть так

import { Component, OnInit, OnDestroy } from '@angular/core';
export class DashboardComponent implements OnInit, OnDestroy {
    ngOnDestroy(){
       if(this.this.subscription){
          this.subscription.unsubscribe();
       }
    }
    // the rest of your code
}

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

0 голосов
/ 07 сентября 2018

Вам необходимо отписываться от подписки каждый раз, когда метод ngOnDestroy в DashBoardComponent.

DashBoardComponent

private subscription:

updateOrder(order): void {
    if(this.this.subscription){
      this.subscription.unsubscribe();
    }
    this.subscription = this.orderService.updateOrder(order).subscribe(next => {
      console.log('updated successfully');
      // This log is never executed even when the update is successful
    }, error => {
      console.log('error while updating order');
    });
  }

ngOnDestroy(){
   if(this.this.subscription){
      this.subscription.unsubscribe();
   }
}
...