Угловой отклик клика - PullRequest
0 голосов
/ 15 ноября 2018

В моем шаблоне у меня есть поле и две кнопки:

<div class="btn-plus" (click)="add(1)"> - </div>
<div class="txt"> {{ myValue }} </div>
<div class="btn-minus" (click)="add(-1)"> + </div>

В моем компонентном файле .ts у меня есть:

add(num) {
    this.myValue +=num;
    this.update(); // async function which will send PUT request
}

Функция this.update() помещает myValue в соответствующее поле большого объекта JSON и отправляет его на сервер.

Проблема : если пользователь нажимает 10 раз в течение короткого периода времени на кнопке плюс / минус, то запрос будет отправлен 10 раз. Но я хочу отправить запрос только один раз - через 0,5 секунды после последнего клика. Как это сделать ?

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Используйте оператор takeUntil:

export class AppComponent  {
  name = 'Angular';

  calls = new Subject();

  service = {
    getData: () => of({ id: 1 }).pipe(delay(500)),
  };

  click() {
    this.calls.next(true);
    this.service.getData().pipe(
      takeUntil(this.calls),
    ).subscribe(res => console.log(res));
  }
}

Stackblitz (откройте консоль, чтобы проверить логи)

0 голосов
/ 15 ноября 2018

Это частично ответ, который я нашел в интернете, но я открыт для более эффективных решений (или улучшения до нижеследующего решения (директива)):

В интернете я нашел директиву appDebounceClick, которая помогает мне следующим образом:

Я удаляю update из add в файле .ts:

add(num) {
    this.myValue +=num;
}

И изменяю шаблон следующим образом:

<div 
    appDebounceClick 
    (debounceClick)="update()" 
    (click)="add(1)" 
    class="btn-plus"
    > - 
</div>
<div class="txt"> {{ myValue }} </div>
<!-- similar for btn-minus -->

БОНУС

Директива appDebounceClick, написанная Кори Райлан (я поставил код здесь на случай, если ссылка перестанет работать в будущем):

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

@Directive({
  selector: '[appDebounceClick]'
})
export class DebounceClickDirective implements OnInit, OnDestroy {
  @Input() debounceTime = 500;
  @Output() debounceClick = new EventEmitter();
  private clicks = new Subject();
  private subscription: Subscription;

  constructor() { }

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

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

  @HostListener('click', ['$event'])
  clickEvent(event) {
    event.preventDefault();
    event.stopPropagation();
    this.clicks.next(event);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...