【发布时间】:2017-04-04 13:29:02
【问题描述】:
这是简短的版本:
我有一个函数:
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)
换句话说,我希望它返回一个接受可能消息的部分函数。但是,我不知道该怎么做!帮助将不胜感激。
这是长版:
我正在尝试构建 elm 可排序表包的“分支”,它使用 elm mdl 包并允许在列标题上自定义事件侦听器。可排序表包(显然)在按该列对表进行排序的列标题上应用事件侦听器。
不幸的是,您不能在同一个元素上拥有两个“onClick”侦听器,因此我决定将自定义消息作为参数传递给排序消息,然后将其作为命令发送排序更新。抱歉,如果您不熟悉该软件包并且这一切听起来都像是胡言乱语,我只是想为我的问题提供上下文。
可排序表包的开发人员创建了一个自定义事件侦听器,如下所示:
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 toMsg 和 columns 都来自项目主视图代码中的配置。 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 )
这基本上是呈现每个元素中包含的数据的地方。所有关于State 和sorter 的内容都与每列的排序配置方式和当前顺序有关。但是你看,这里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 不是一个函数(因为在类型定义中它不期望一个参数)。
对不起,我解释得这么糟糕!我真的很想在我去的时候弄清楚,所以我很感激你的耐心。
【问题讨论】:
标签: elm