TimLariviere / Fabulous-new

Fabulous v2 - Work in progress
https://timothelariviere.com/Fabulous-new/
Other
41 stars 3 forks source link

[Architecture] Support composing widgets with different message types #11

Closed TimLariviere closed 2 years ago

TimLariviere commented 2 years ago

In v1, we were exposing dispatch in the view function and it was up to the developers to map messages to the right root type.

type Msg =
    | SubPageMsg of SubPage.Msg

let view model dispatch =
   SubPage.view model.SubModel (SubPageMsg >> dispatch)

This was possible because we weren't strongly typing the views (everything is ViewElement).

dispatch is a function internal to Fabulous and it's better to not leak it for the view function where it can be misused.
To avoid this, in v2 we're strongly typing the widgets (eg. ContentPage<SubPage.Msg>) and Fabulous takes care of dispatching internally without exposing it to the developers.

But this strong typing prevents composing widgets of different msg types.

NavigationPage([
    MainPage.view model.MainPageModel
    DetailPage.view model.DetailPageModel // Error: Expected to be ContentPage<MainPage.Msg>, but was ContentPage<DetailPage.Msg>
])

So to change the msg type from one to another (ContentPage<MainPage.Msg> => ContentPage<DetailPage.Msg>), having a mapping function would be necessary

type Msg =
    | MainMsg of MainPage.Msg
    | DetailMsg of DetailPage.Msg

NavigationPage([
    Widget.map MainMsg (MainPage.view model.MainPageModel)
    Widget.map DetailMsg (DetailPage.view model.DetailPageModel)
])