mat-slider change 事件触发太频繁

Cin*_*ode 1 angular-material angular

我正在使用垫子滑块让用户设置一个值。该(input)事件发射器用于显示值“活”(而鼠标仍下跌)。这是有效的。目前,(change)事件发射器用于识别用户何时选择了一个值(释放鼠标)。

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

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

我已经尝试用锁来实现这一点,但它不起作用,因为有时只触发一个更改事件(例如,单击滑块而不是拖动它时),然后错误地翻转了锁定变量和锁定机制由于倒置变量而不再工作。

有没有办法解决这些问题并实现我想要的?

Gio*_*ren 7

您可以使用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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

上面的组件包含一个绑定到输入事件的滑块。每次值更改时,此输入事件都会触发,不会延迟。该valueSubject获得新值每一次onSlide被调用,但由于debounceTime(1000)的用户只会收到任何新的价值时,有过至少一个完整秒(或1000毫秒)自上次值发生变化。


Dom*_*nik 5

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

解决方法:使用事件slideend

<mat-slider
  #mySlider
  (slideend)="sliderOnChange(mySlider.value)"
></mat-slider>
Run Code Online (Sandbox Code Playgroud)

这是“真实的”(预期的)“变化”事件。

更新:已知问题:使用(slideend)时,只需单击滑块的范围线就不会触发滑动端,直到它从未被拖动为止。您也可以监听 (mouseup) 事件或 (pointerup)。但是对于指针向上等,您的鼠标光标必须位于组件内部。(重叠)否则你必须处理指针的中止事件。...

我找到了幻灯片结束/指针向上问题的解决方案。只需将其与简单的变化检测结合起来即可。

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

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