在使用可重用组件时,还不太清楚如何在模块之间发送消息。
我有一个扩展的文本区域,我想在网站上的许多不同部分中使用。文本区域接受组成用户操作的HTML部分。通常处理提交,取消,上传图标等。
尝试写一个我正在谈论的内容的简单示例,而无需在此处添加大量代码。因此,从本质上讲,我只想插入并播放已经附带的HTML插件。
我假设CancelNote被作为TextArea消息触发,因此它永远不会看到Cancel Note消息。不知道如何在这里使用Html.map(或者即使我愿意).....感觉像即插即用的方法可能是一个不好的方法,但是不确定我如何才能实现不错的可重用性。
SEPERATE MODULE
update model msg =
case msg of
CancelText ->
( { model | note = (Just "") }
, Cmd.none
)
view: stuff
view stuff =
......
TextArea.view
(button [ Html.Events.onClick CancelText] [])
TEXT AREA MODULE
view : Html.Html msg -> Html msg
view actionHtml =
div [ class "extended_text_area_container" ] [
textarea [] [
]
, actionHtml
]
答案 0 :(得分:2)
消息只是其他值。您可以直接将它们传递出去:
-- SEPERATE MODULE
view: stuff
view stuff =
......
TextArea.view CancelText
-- TEXT AREA MODULE
view : msg -> Html msg
view msg =
div [ class "extended_text_area_container" ]
[ textarea [] []
, button [ onClick msg ] []
]
编辑:如果您还需要维护内部状态,只需使用另一条消息告诉父级更新状态即可:
-- Main module
type msg =
...
SetTextAreaState TextArea.state
update model msg =
case msg of
...
SetTextAreaState state ->
{ model | textAreaState = state }
view : Model -> Html msg
TextArea.view SetTextAreaState model.textAreaState
-- TextArea module
type State =
...
type Msg =
Clicked
update : State -> Msg -> State
update state msg =
case msg of
Clicked ->
{ state | clicked = True }
view : (State -> msg) -> State -> Html msg
view toMsg state =
let
updateAndWrap msg =
toMsg (update state msg)
in
div [ class "extended_text_area_container" ]
[ textarea [] []
, button [ onClick (updateAndWrap Clicked) ] []
]
这里,不是直接在msg
中将onClick
传递给TextArea.view
,而是调用一个函数来更新状态,然后将其包装在从中传入的msg
构造函数中父母,这将产生一条消息,我们对此一无所知。
此外,尽管我使用内部Msg
类型和update
函数类似于整个Elm体系结构,但这绝不是强制性的。这是一种很好的实现方式,因为它很熟悉并且可扩展。