尝试阻止默认设置时,键入带有自定义keydown事件的错误

dav*_*ner 2 events elm

我意识到我一定在某个地方缺少一个论点,或者我的一个论点是不正确的,但是在尝试了所有我能想到的东西之后,我不确定该怎么做。

handleKeyDown : msg -> Attribute (Int -> Msg)
handleKeyDown message =
    custom "keydown" (Json.succeed { message = KeyPressed, stopPropagation = True, preventDefault = True })

view : Model -> Html Msg
view model =
    div []
        [ input
            [ handleKeyDown ]
            [ text "" ]
        ]
Run Code Online (Sandbox Code Playgroud)

错误

The 1st argument to `input` is not what I expect:

104|         [ input
105|>            [ handleKeyDown ]
106|             [ text "" ]

This argument is a list of type:

    List #(msg -> Attribute (Int -> Msg))#

But `input` needs the 1st argument to be:

    List #(Attribute msg)#
Run Code Online (Sandbox Code Playgroud)

gle*_*nsl 5

这里有几个问题:

  1. handleKeyDown期望message您不使用也不传递参数。因此,类型msg -> Attribute ...不是Attribute ...预期的那样。

  2. KeyPressed似乎具有类型的有效负载Int。因此,返回值为Attribute (Int -> Msg)而不是Attribute Msg

假设您要使用message参数并keyCode从事件中获取,则此方法应该有效:

handleKeyDown : (Int -> Msg) -> Html.Attribute Msg
handleKeyDown tag =
    let
        options message =
            { message = message
            , stopPropagation = True
            , preventDefault = True
            }

        decoder =
            Json.field "keyCode" Json.int
                |> Json.map tag
                |> Json.map options
    in
    Html.Events.custom "keydown" decoder

view : Model -> Html Msg
view model =
    div []
        [ input
            [ handleKeyDown KeyPressed ]
            [ text "" ]
        ]
Run Code Online (Sandbox Code Playgroud)

在这里,handleKeyDown期望带有Int有效负载的标签/消息。内部事件解码器检索keyCode,将其包装在您传入的标签中,然后使用将其包装在options对象中preventDefault = True

但是请注意,keyCode不建议使用,您可能要使用codekey代替,它们都是字符串。