【问题标题】:How to debounce elm signals?如何去抖动 elm 信号?
【发布时间】:2016-01-10 18:59:41
【问题描述】:

我正在使用start-app 来塑造我的应用程序。 Html.Events 支持使用自定义Signal.message 创建自定义事件。但是如何发送该消息是在 Html 库后面抽象的。还有一个名为实现去抖动的库 (http://package.elm-lang.org/packages/Apanatshka/elm-signal-extra/5.7.0/Signal-Time#settledAfter)。

SearchBar.elm:

module PhotosApp.SearchBar (view) where

import Html exposing (input, div, button, text, Html)
import Html.Events exposing (on, onClick, targetValue)
import Html.Attributes exposing (value, type')

import Effects exposing (Effects, Never)

import PhotosApp.Actions as Actions

onTextChange : Signal.Address a -> (String -> a) -> Html.Attribute
onTextChange address contentToValue =
    on "input" targetValue (\str -> Signal.message address (contentToValue str))

view : Signal.Address Actions.Action -> String -> Html
view address model =
    div []
        [ input  [ type' "text", value model, onTextChange address Actions.Search] []
        , button [ onClick address Actions.Clear ] [text "Clear"]
        ]

【问题讨论】:

    标签: elm


    【解决方案1】:

    在绑定@Apanatshka 的settledAfter 函数之前,您可以通过代理邮箱设置从 HTML 属性中去抖动。

    (请注意,由于您使用的是 StartApp,我们无法直接访问主地址,因此我不得不通过忽略传递给 @987654324 的 address 来破坏其中一些功能@. 你可以通过不使用 StartApp 获得更通用的东西,但这应该可以帮助你开始)

    由于事件属性不能直接创建任务,我们必须使用中间代理邮箱。我们可以这样设置:

    debounceProxy : Signal.Mailbox Action
    debounceProxy =
      Signal.mailbox NoOp
    

    请注意,上述函数需要 NoOp 动作,这在 Elm 架构中很常见,这意味着 update 函数不会对模型进行任何更改。

    现在我们需要设置另一个 Signal 来监听代理邮箱,然后通过 settledAfter 函数传递信号。我们可以这样定义这个信号:

    debounce : Signal Action
    debounce =
      settledAfter (500 * Time.millisecond) debounceProxy.signal
    

    我们现在可以将onTextChange 函数更改为指向代理邮箱。请注意,我已经删除了第一个 Address 参数,因为它被忽略了(请参阅我之前关于符合 StartApp 的评论):

    onTextChange : (String -> Action) -> Html.Attribute
    onTextChange contentToValue =
        on "input" targetValue (\str -> Signal.message debounceProxy.address (contentToValue str))
    

    最后,您必须将 debounce 信号绑定到 StartApp 的 inputs 参数中,这意味着您对 start 的调用将如下所示:

    app = StartApp.start
      { init = init
      , update = update
      , view = view
      , inputs = [ debounce ]
      }
    

    我已将完整的工作示例粘贴到 gist here

    【讨论】:

    • 感谢 start-app 集成 :) 是否可以在较低级别而不是较高级别的 debounce 函数中定义 debounce timout?
    • 您可以像这样将Time 参数传递给debouncedebounce interval = settledAfter interval debounceProxy.signal,然后您可以像这样在StartApp 中设置它:inputs = [ debounce (500 * Time.millisecond) ]
    • 是的,但仍然是在更高级别定义的。因此,为不同的输入提供不同的去抖动值似乎很复杂。
    • 您实际上不需要在顶层定义debounce 函数。您可以改为将信号映射函数传递给inputs,如下所示:inputs = [ settledAfter (500 * Time.millisecond) debounceProxy.signal, settledAfter (1000 * Time.millisecond) debounceProxy2.signal ]
    • 当然可以,但输入仍然是顶级配置。
    猜你喜欢
    • 1970-01-01
    • 2017-01-30
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多