Отправка сообщений между модулями - PullRequest
1 голос
/ 23 июня 2019

Не могу понять, как отправлять сообщения между модулями при работе с повторно используемыми компонентами.

У меня есть расширяющаяся текстовая область, которую я хотел бы использовать в различных разделах сайта. Текстовая область принимает часть HTML, которая составляет действия пользователя. Как правило, обработка отправки, отмены, загрузки значков и т. Д.

Пытался написать краткий пример того, о чем я говорю, не бросая тонны кода здесь. По сути, я хотел бы просто подключить и воспроизвести фрагменты HTML, которые уже присоединены.

Я предполагаю, что CancelNote запускается как сообщение TextArea, поэтому оно никогда не увидит сообщение Cancel Note. Не уверен, как бы я использовал Html.map здесь (или даже если бы я это сделал) ..... чувствую, что метод plug and play, вероятно, плохой подход, но не уверен, как еще я мог бы добиться приличного повторного использования.

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
    ]

1 Ответ

2 голосов
/ 23 июня 2019

Сообщения - это просто значения, как и любые другие. Вы можете передать их напрямую:

-- 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, это никоим образом не является обязательным. Это просто хороший способ сделать это, так как он знаком и хорошо масштабируется.

...