Here's how my Elm app is currently structured:
Types.elm:
import Pages.Login.Types as Login
import Pages.Dashboard.Types as Dashboard
type Page = LoginPage
| DashboardPage
type Msg = LoginMsg Login.Msg
| DashboardMsg Dashboard.Msg
| NavigationStart Page
| NavigationEnd Page
type Model = LoginModel Login.Model
| DashboardModel Dashboard.Model
Login.elm:
import Pages.Login.Types as PageTypes
import Types
view : (PageTypes.Msg -> msg) -> PageTypes.Model -> Html msg
view = -- some code
I'm stuck with the following, seemingly, competing requirements:
- Trying to keep the pages fairly independent of each other, where their
Msg
andModel
types can be reasoned about independently - Making pages aware of each other's existence (at the type-level) so that their view/update functions can emit the
NavigationStart page
msg to navigate between each other.
What is the best way to achieve this in Elm?
If you want to issue top level navigation messages from a sub-page's
view
, there's nothing wrong with concretely returning the top level message type, such as:If you insist on abstracting the message type as indicated, you can pass an extra argument for the navigation messages:
and have the top level view function pass
NavigationStart
as the first argument.Finally, if you need the sub-page's
update
to be able to trigger top-level navigation, you can put that information in the return value:In general: It's fine to adapt the types of the view and update functions for you sub-pages to fit your specific requirements!