如何防止在Angular中进行多个订阅调用?

时间:2019-02-25 09:55:07

标签: angular typescript subscription

我有一个消息服务,可以在各个组件之间进行交互。当我单击Mine按钮时,我只想触发一条消息。到目前为止,该方法有效。但是,当我单击<>按钮时,它会触发getMessage(),因此它会累加值。但是,我只想在单击Mine时发送一个值。仅最后一个值。在单击getMessage()<时如何防止触发>

当我点击<>时,它会在1到10张卡之间切换。当我点击Mine时,它应该只拿走我正在使用的卡并发送从该块到另一个组件的信息。但是,相反,当我单击<>时,getMessage()被呼叫,它将累加所有卡,直到我单击Mine。我该如何预防?

遵循一些代码。我试图使其紧凑:

Message-service.ts:

@Injectable({ providedIn: 'root' })
export class MessageService {
  private subject = new Subject<any>();

  sendMessage(message: string) {
    this.subject.next({ text: message });
  }

  getMessage(): Observable<any> {
    console.log('Get Message Message Service');
    return this.subject.asObservable();
  }

矿工卡组件:

  message: any;
  subscription: Subscription;

  constructor(private ref: ChangeDetectorRef, private emitTransactionService: EmitTransactionService,
              private messageService: MessageService) {
    this.subscription = this.messageService.getMessage().subscribe(message => {
      console.log('Constructor miner-card'); // gets called multiple times, depending on how often I click < and >. When I click 10 times on < or > it will call this subscription 10 times.
    });
  }

当我单击<>时,这些函数被调用: 根据minerCounter的值,将显示卡1-10。

  precedingBlock() {
    this.minerCounter--;

    if (this.minerCounter < 1) {
      this.minerCounter = 10;
    }
  }

  nextBlock() {
    this.minerCounter++;

    if (this.minerCounter > 10) {
      this.minerCounter = 1;
    }
  }

通过<>按钮,卡片的外观如何:

enter image description here

Mine按钮:

enter image description here

3 个答案:

答案 0 :(得分:2)

您应始终unsubscribe ngOnDestroy中的订阅。

  message: any;
  subscription: Subscription;

  constructor(private ref: ChangeDetectorRef, private emitTransactionService: EmitTransactionService,
              private messageService: MessageService) {
    this.subscription = this.messageService.getMessage().subscribe(message => {
      console.log('Constructor miner-card'); // gets called multiple times, depending on how often I click < and >. When I click 10 times on < or > it will call this subscription 10 times.
    });
  }

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

答案 1 :(得分:0)

检查您的订阅是否未定义。如果未定义,则仅订阅。

constructor(
private ref: ChangeDetectorRef,
private emitTransactionService: EmitTransactionService,
private messageService: MessageService
) {
if (!this.subscription) {
    this.subscription = this.messageService.getMessage().subscribe(message => {
      console.log('Constructor miner-card'); // gets called multiple times, depending on how often I click < and >. When I click 10 times on < or > it will call this subscription 10 times.
    });
  }
}

答案 2 :(得分:0)

在您的miner-card.component.ts文件中,使用take(1)。这样只会从订阅中获取单个数据。

  message: any;
  subscription: Subscription;

  constructor(private ref: ChangeDetectorRef, private emitTransactionService: EmitTransactionService,
              private messageService: MessageService) {
    this.subscription = this.messageService.getMessage().pipe(take(1)).subscribe(message => {
      console.log('Constructor miner-card'); // gets called multiple times, depending on how often I click < and >. When I click 10 times on < or > it will call this subscription 10 times.
    });
  }

希望这会有所帮助!