自定义事件侦听器

时间:2017-04-04 13:29:02

标签: elm

以下是简短版本:

我有一个功能:

onClick : String -> Bool -> (State -> msg) -> Options.Property c msg
onClick name isReversed toMsg =
    Options.on "click" <| Json.succeed <|
    toMsg (State name isReversed)

我想将功能更改为:

onClick : String -> Bool -> (State -> msg) -> (Maybe msg -> Options.Property c msg)

换句话说,我希望它返回一个带有Maybe msg的部分函数。但是,我不知道该怎么做!帮助将不胜感激。

这是长版:

我正试图建立一个&#39; fork&#39; elm可排序表包的使用elm mdl包并允许列标题上的自定义事件侦听器。可排序的表包(显然)在列标题上应用事件侦听器,按该列对表进行排序。

不幸的是,你不能有两个onClick&#39;同一个元素上的监听器,所以我决定将自定义消息作为参数传递给排序消息,然后将其作为排序更新中的命令发送。对不起,如果你不熟悉这个软件包,并且听起来像是一个笨蛋,我只是想我会给出我的问题的背景。

可排序表包的开发人员创建了一个自定义事件侦听器,如下所示:

onClick : String -> Bool -> (State -> msg) -> Attribute msg
onClick name isReversed toMsg =
  E.on "click" <| Json.map toMsg <|
    Json.map2 State (Json.succeed name) (Json.succeed isReversed)

我已经改变了一点使用mdl自定义事件监听器并使其(在我看来)稍微更具可读性:

onClick : String -> Bool -> (State -> msg) -> Options.Property c msg
onClick name isReversed toMsg =
    Options.on "click" <| Json.succeed <|
    toMsg (State name isReversed)

正如我所说,我希望如此:

onClick : String -> Bool -> (State -> msg) -> (Maybe msg -> Options.Property c msg)

但是,如果您熟悉该软件包并在点​​击列时使用自定义消息有任何其他建议,请提出建议!我真的不知道我在做什么。

版本较长:

在组件的视图代码中,有一个变量theadDetails,如下所示:

theadDetails = 
customizations.thead (List.map (toHeaderInfo state toMsg columns)

state toMsgcolumns都来自项目主视图代码中的配置。 toMsg是一个在主更新中处理的消息(该组件不跟踪其自身的状态)。

toHeaderInfo看起来像这样:

toHeaderInfo : State -> (State -> msg) -> ColumnData data msg -> ( String, Status, Options.Property c msg )
toHeaderInfo (State sortName isReversed) toMsg { name, sorter } =
    case sorter of
        None ->
            ( name, Unsortable, onClick sortName isReversed toMsg )

        Decreasing _ ->
            ( name, Sortable (name == sortName), onClick name False toMsg )

        IncOrDec _ ->
            if name == sortName then
                ( name, Reversible (Just isReversed), onClick name (not isReversed) toMsg )
            else
                ( name, Reversible Nothing, onClick name False toMsg )

这基本上是将呈现每个元素中包含的数据的位置。关于Statesorter的所有这些内容都与每个列的排序配置方式和当前订单有关。但是你看,这里调用了onClick并传递了必需的参数。

正如您在theadDetails中看到的那样,此信息将传递给函数customizations.tHead,如下所示:

defaultCustomizations : Customizations data msg c
defaultCustomizations =
    { tableAttrs = []
    , caption = Nothing
    , thead = simpleThead
    , tfoot = Nothing
    , tbodyAttrs = []
    , rowAttrs = simpleRowAttrs
    }


simpleThead : List ( String, Status, Options.Property { numeric : Bool, sorted : Maybe Table.Order } msg ) -> HtmlDetails {} msg
simpleThead headers =
    HtmlDetails [] (List.map simpleTheadHelp headers)


simpleTheadHelp : ( String, Status, Options.Property { numeric : Bool, sorted : Maybe Table.Order } msg ) -> Html msg
simpleTheadHelp ( name, status, onClick ) =
    let
        check =
            Debug.log "status" status

        attrs =
            case status of
                Unsortable ->
                    []

                Sortable selected ->
                    if selected then
                        [ onClick
                        , Options.css "color" "rgb(0,0,0)"
                        ]
                    else
                        [ onClick ]

                Reversible Nothing ->
                    [ onClick
                    ]

                Reversible (Just isReversed) ->
                    [ onClick
                    , Options.css "color" "rgb(0,0,0)"
                    ]
    in
        Table.th attrs [ Html.text name ]

正是在这里,我想通过最后的论证。所以simpleTheadHeald会变成:

simpleTheadHelp : ( String, Status, Options.Property { numeric : Bool, sorted : Maybe Table.Order } msg ) -> Html msg
simpleTheadHelp ( name, status, onClick ) =
    let
        check =
            Debug.log "status" status

        attrs =
            case status of
                Unsortable ->
                    []

                Sortable selected ->
                    if selected then
                        [ onClick Nothing
                        , Options.css "color" "rgb(0,0,0)"
                        ]
                    else
                        [ onClick Nothing ]

                Reversible Nothing ->
                    [ onClick Nothing
                    ]

                Reversible (Just isReversed) ->
                    [ onClick Nothing
                    , Options.css "color" "rgb(0,0,0)"
                    ]
    in
        Table.th attrs [ Html.text name ]

然而,这给了我一个错误,说onClick不是一个函数(因为在类型定义中它不是期望参数)。

很抱歉做了这么糟糕的工作来解释自己!在我走的时候,我真的想弄清楚,所以我很感激耐心。

1 个答案:

答案 0 :(得分:1)

我不熟悉这个包,所以如果我在你的问题中遗漏了一些东西或者告诉了你已经知道的东西,我会道歉。

榆树中的功能会自动调整。您需要做的就是为函数传递一组不完整的参数,然后您将获得一个带有剩余参数的函数。所以这将是你的功能签名:

onClick : String -> Bool -> (State -> msg) -> Maybe msg -> Options.Property c msg
onClick name isReversed toMsg maybeMsg =

然后使用所有参数编写函数,而不必担心部分应用程序。仅使用前三个参数调用该函数,如下所示:

onClick "myName" True MyMsg

将自动返回带有此签名的函数:

newFunction : Maybe msg -> Options.Property c msg

您不需要做任何其他事情。

相关问题