垫滑块更改事件触发得太多

时间:2019-02-15 12:31:16

标签: angular angular-material

我正在使用垫滑块让用户设置一个值。 (input)事件发射器用于显示“实时”值(鼠标仍处于按下状态)。 可以了 目前,(change)事件发射器用于识别用户何时选择了值(释放的鼠标)。

第一个问题是,在与滑块正常交互期间,更改事件被触发两次:第一次单击滑块时第二次,释放滑块时第二次。 我想让事件仅在释放滑块时触发,或者希望有一个函数可以区分两个事件并仅对释放事件起作用。

第二个问题是,当设置了滑块的新值时,我必须发出HTTP请求。我不希望这种情况经常发生,所以我希望有一个超时时间。仅当经过一定时间并且没有发生新的更改事件时,我才要发出HTTP请求。

我已经尝试使用锁来实现这一点,但是它没有用,因为有时仅触发一个change事件(例如,单击滑块而不拖动时),然后将lock变量错误地翻转,由于变量反转,锁定机制不再起作用。

有什么办法可以解决这些问题并实现我想要的?

2 个答案:

答案 0 :(得分:2)

这是一个错误。参见https://github.com/angular/material2/issues/14363

解决方法: 使用事件slideend

<mat-slider
  #mySlider
  (slideend)="sliderOnChange(mySlider.value)"
></mat-slider>

这是“真实”(预期)“更改”事件。

更新: 已知问题:使用(幻灯片)在幻灯片的范围线上单击,直到从未拖动过幻灯片,都不会触发幻灯片。或者,您可以监听(mouseup)事件或(pointerup)。但是,使用pointerup等时,鼠标光标必须位于组件内部。 (重叠),否则您必须处理指针的中止事件。 ...

我找到了解决slideend / pointerup问题的解决方案。只需将其与简单的更改检测结合即可。

<mat-slider
  #mySlider
  (slideend)="sliderOnChange(mySlider.value)"
  (pointerup)="sliderOnChange(mySlider.value)"
></mat-slider>
sliderOnChange(value: number) {
  if (this.mySliderValue!== value) {
    this.mySliderValue= value;
    console.log('changed: ', value);
  }
}

您也可以添加keyup-event来处理键盘输入。

答案 1 :(得分:0)

您可以使用debounceTime确保在触发HTTP请求之前,事件之间存在一定的时间延迟。

示例:

@Component({template: `<mat-slider (input)="onSlide($event)"></mat-slider>`})
export class DelayedSliderComponent implements OnInit {
    valueSubject = new BehaviorSubject<number>(0);

    ngOnInit() {
        this.valueSubject.pipe(debounceTime(1000)).subscribe(value => {
            // http request can go here
        });
    }

    onSlide(event: MatSliderChange) {
        this.valueSubject.next(event.value);
    }
}

上面的组件包含一个绑定到输入事件的滑块。该输入事件每一次更改值都会触发一次,而不会延迟。每次调用 onSlide 时, valueSubject 都会获取新值,但是由于 debounceTime(1000),订户将仅在以下时间收到新值:自上次更改值以来,至少有一整秒(或1000毫秒)。