我的Elm应用当前的结构如下:
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
我坚持以下看似竞争的要求:
Msg
和Model
类型进行独立推理NavigationStart page
消息,以在彼此之间导航。在榆木中实现此目标的最佳方法是什么?
答案 0 :(得分:2)
查看Richard Feldman的单页示例存储库here。本质上,您有一个顶级应用程序,该应用程序每页管理每个模型\视图\更新。
答案 1 :(得分: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
...
通常:可以根据您的特定需求为子页面调整视图类型和更新功能!