3

这是我的 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

登录.elm:

import Pages.Login.Types as PageTypes
import Types

view : (PageTypes.Msg -> msg) -> PageTypes.Model -> Html msg
view = -- some code 

我坚持以下看似相互竞争的要求:

  • 试图保持页面彼此相当独立,它们MsgModel类型可以独立推理
  • 使页面知道彼此的存在(在类型级别),以便它们的视图/更新功能可以发出NavigationStart page消息以在彼此之间导航。

在 Elm 中实现这一目标的最佳方法是什么?

4

2 回答 2

2

在此处查看 Richard Feldman 的单页示例 repo 。本质上,您有一个顶级应用程序,它管理每个页面的每个模型\视图\更新。

于 2018-06-24T14:26:47.567 回答
0

如果要从子页面发出顶级导航消息view,具体返回顶级消息类型并没有错,例如:

 view : Login.Model -> Html Types.Msg

如果您坚持按指示抽象消息类型,则可以为导航消息传递一个额外的参数:

view : (Types.Page -> msg) -> (Login.Msg -> msg) -> Login.Model -> Html msg
view navigateTo wrapPageMsg model = ...

并将顶级视图函数NavigationStart作为第一个参数传递。

最后,如果您需要子页面update能够触发顶级导航,您可以将该信息放入返回值中:

-- Login.update, updates the model and
-- optionally returns a navigation destination
update : Login.Msg -> Login.Model -> (Login.Model, Maybe Types.Page)

-- top level update
update : Msg -> Model -> Model
update msg model =
    let
        -- navigation helper
        navigateTo page model = ...
    in
    case (msg, model) of
        (NavigationStart p, _) ->
            navigateTo p model
        (LoginMsg lmsg, LoginModel lmodel) ->
            let
                (newlmodel, navigate) = Login.update lmsg lmodel
            in
            case navigate of
                Just p ->
                    navigateTo p model
                Nothing ->
                    LoginModel newlmodel
        ...

一般来说:可以为您的子页面调整视图类型和更新功能以满足您的特定要求!

于 2018-08-16T10:57:48.763 回答