How to debounce message handling? #1061
-
All the issues an merged PRs on this topic are years old and the debounce method introduced by #237 doesn't seem to exist any longer. Use case: I have a NumericUpDown the value of which I'd like to serialize into some settings to be reloaded on app startup. Now because you can change the value of this widget rapidly using the mouse wheel, I don't want to persist it on every value change, but only after some time. Ideally I'd like to debounce the saving, not the message itself, i.e. in the update function:
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Unlike in Fabulous 1 where we could debounce several events and only dispatch the message one time, Fabulous 2 doesn't expose the dispatch function anymore for convenience and security, so the same trick is not possible. Instead, you would need to handle the debouncing yourself using 2 messages: one for reacting to every events and one for the actual change. Like so: let debounce (timeout: int) (fn: unit -> 'msg) =
let mutable cts: CancellationTokenSource = null
fun () ->
Cmd.ofSub (fun dispatch ->
if cts <> null then
cts.Cancel()
cts.Dispose()
cts <- new CancellationTokenSource()
Device.StartTimer(TimeSpan.FromMilliseconds(float timeout), (fun () ->
if not cts.IsCancellationRequested then
cts.Dispose()
cts <- null
dispatch (fn())
false // Do not let the timer trigger a second time
))
) type Model =
{ Padding: int }
type Msg =
| PaddingChanged of int
| SaveSettings
let requestSaveSettings = debounce 300 (fun () -> SaveSettings)
let update msg model =
match msg with
| PaddingChanged newValue -> { model with Padding = newValue }, requestSaveSettings()
| SaveSettings -> model, saveSettings model |
Beta Was this translation helpful? Give feedback.
-
@TimLariviere Thank you for prompt response - I can see clearly now! Getting access to
You might want to update and extend the doco there too to avoid this confusion. You can ignore this question of mine - it's from before I found |
Beta Was this translation helpful? Give feedback.
Unlike in Fabulous 1 where we could debounce several events and only dispatch the message one time, Fabulous 2 doesn't expose the dispatch function anymore for convenience and security, so the same trick is not possible.
Instead, you would need to handle the debouncing yourself using 2 messages: one for reacting to every events and one for the actual change. Like so: