简体   繁体   English

Angular中多个复选框的去抖功能

[英]Debounce functionality for multiple checkboxes in Angular

I am trying to apply debounce time for multiple check boxes in Angular 7. The idea is to delay the api calls for x seconds in order to have better performing application (checking/unchecking the checkboxes invokes a call to the API). 我试图在Angular 7中为多个复选框应用去抖时间。想法是延迟api调用x秒以便具有更好的执行应用程序(检查/取消选中复选框调用API)。

Each checkbox corresponds to a filter which is sent to the backend when checked/unchecked and that determines the result returned from the server. 每个复选框对应一个过滤器,该过滤器在选中/取消选中时发送到后端,并确定从服务器返回的结果。 I have tried using a custom debounce directive suggested in the article mentioned here, https://coryrylan.com/blog/creating-a-custom-debounce-click-directive-in-angular 我尝试过使用这里提到的文章中提出的自定义去抖指令, https://coryrylan.com/blog/creating-a-custom-debounce-click-directive-in-angular

The problem addresses debounce for a single input field, in my case if I check and uncheck a single checkbox multiple times within the debounce time, only of call to the backend is made no matter how many times I click it. 这个问题解决了单个输入字段的去抖动问题,在我的情况下,如果我在去抖动时间内多次检查并取消选中一个复选框,则无论多少次点击它都会调用后端。 But my problem is with checking/unchecking multiple checkboxes and have only one request made to the API with in the debounce time. 但我的问题是检查/取消选中多个复选框,并且在去抖时间内只向API发出一个请求。 Right now a call to the api is made every time I click on the checkbox which does not address my issue. 现在每次点击没有解决我的问题的复选框时都会调用api。

Following is the directive I am using which is similar to the example in the article: 以下是我使用的指令,类似于文章中的示例:

import { Output, EventEmitter, OnInit, OnDestroy, Directive, ElementRef  } from '@angular/core';
import { debounceTime } from 'rxjs/operators';
import { HostListener } from '@angular/core';
import { Subscription, Subject } from 'rxjs';

@Directive({
  selector: '[appDebounceClick]'
})
export class DebounceDirective implements OnInit, OnDestroy{

  @Output() debounceClick = new EventEmitter();
  private clicks = new Subject();
  private subscription: Subscription;

  constructor(private elementRef: ElementRef) { }

  ngOnInit() {
    this.subscription = this.clicks.pipe(
      debounceTime(2000)
    ).subscribe(e => this.debounceClick.emit(e));
  }

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

  @HostListener('change', ['$event'])
    clickEvent(event) {
    this.clicks.next(event);
  }
}

Following is the code in my template: 以下是我的模板中的代码:

<ng-container *ngFor="let checkbox of checkboxList">
  <mat-checkbox *ngIf="checkbox.name == 'test'"  [(ngModel)]="checkbox.selected" appDebounceClick (debounceClick)="onChange($event,checkbox)" >
    {{checkbox.name}}
  </mat-checkbox>
</ng-container>

I feel the issue here is the Directive is applied to every checkbox which in turn creates a new Observable/Subject which only associated with an individual checkbox . 我觉得这里的问题是指令适用于每个复选框,而这些复选框又创建了一个新的Observable / Subject,它只与一个单独的复选框相关联。 I think there should be just one Subject to which the click events on the checkboxes be subscribes to, but I am not entirely sure how to implement that. 我认为应该只有一个主题,复选框上的点击事件可以订阅,但我不完全确定如何实现。 Would appreciate any thoughts on this issue or any better ideas on solving this problem. 对这个问题的任何想法或解决这个问题的任何更好的想法表示感谢。

You can use a Service to centralize the Subject , obviously the Service has to be Singleton so that all the checkboxes emits to one Subject and the debounceTime operator acts for all elements. 您可以使用服务来集中Subject ,显然服务必须是Singleton以便所有复选框都发送到一个Subject, debounceTime操作符用于所有元素。

On the other hand, you can implement the same behavior but in the parent component, I mean, the Subject has to be placed in the parent component. 另一方面,您可以实现相同的行为,但在父组件中,我的意思是,Subject必须放在父组件中。

The decision depends on reusability matters. 决定取决于可重用性问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM