Angular 6订阅多次调用

时间:2018-09-07 07:15:27

标签: angular rxjs observable angular2-observables subject-observer

我刚刚开发了一个新的Angular 6 WebApp,该组件之间的整个通信都是基于主题和订阅。

整个订阅都在仪表板组件(根目录下的1级)中实现。在仪表板上,该组件是一个从带有SignalR Web套接字的C#ASP.NET Core后端生成的表。

现在,我们为该表中的每一行实现了编辑和删除按钮。 编辑按钮将打开一个ngx-bootstrap Modal。模态打开功能在参数中获取单行信息。

在此“编辑模式”内有一些带有行日期的输入。现在,当我保存更改时,数据将发送回仪表板组件,该组件将使用.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(后端)之间的桥梁)中更新订单

  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 :(得分:0)

每次在DashBoardComponent中使用ngOnDestroy方法时,都需要取消订阅。

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

答案 1 :(得分:0)

出于调试目的,我向仪表板组件添加了更多日志。我在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

的屏幕截图

the new industry standard

答案 2 :(得分:0)

在您的仪表板组件中,我看不到导出类表达式,请检查您是否实现了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的函数,除非您手动调用它,否则该函数将不会执行。