Моя основная программа имеет update
функцию
update : Msg -> Model -> ( Model, Cmd Msg )
Для связи с подкомпонентами мы можем добавить другой вариант и обернуть наши сообщения в новое сообщение
type alias Model =
{ ...
, child : Child.Model
}
type Msg
= ...
| ChildMsg Child.Msg
update msg model =
case msg of
...
ChildMsg childMsg ->
let
( childModel, cmd ) =
Child.update childMsg model.child
updatedModel =
{ model | child = childModel }
childCmd =
Cmd.map ChildMsg cmd
in
( updatedModel, childCmd )
Однако это кажется сложной задачей, если тип функции update
моего подкомпонента не соответствует родительскому. Рассмотрим ребенка с функцией полиморфного обновления:
-- PolymorphicChild.elm
update : Msg a -> Model -> ( Model, Cmd (Msg a) )
При запуске команды из этого модуля я должен обернуть ее
PolymorphicChild.someCommand : Cmd (Msg Foo)
PolymorphicChild.someCommand
|> Cmd.map PolymorphicChild
Однако при этом получается Msg (PolymorphicChild.Msg Foo)
, а не Msg PolymorphicChild.Msg
, ожидаемое моим приложением.
The right side of (|>) is causing a type mismatch.
(|>) is expecting the right side to be a:
Cmd (PolyMorphicChild.Msg Foo) -> a
But the right side is:
Cmd Polymorphic.Msg -> Cmd Msg
Я попытался добавить полиморфный параметр к App.Msg
-- App.elm
type Msg a =
= ..
| PolymorphicChildMsg (PolymorphicChild.Msg a)
Но это в основном взрывает всю мою программу. Каждую функцию, включающую App.Msg
, необходимо каким-то образом изменить для работы с новым дочерним компонентом.
Как я могу объединить два типа и заставить два компонента работать вместе?