Как одна страница может послать сообщение, чтобы перейти на другую страницу в Elm? - PullRequest
0 голосов
/ 24 июня 2018

Вот как в настоящее время структурировано мое приложение 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 для навигации между ними.

Каков наилучший способ добиться этого вElm

Ответы [ 2 ]

0 голосов
/ 16 августа 2018

Если вы хотите выдавать навигационные сообщения верхнего уровня из 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
        ...

В целом: можно адаптировать типы представлений и функций обновления для своих подстраниц в соответствии с вашими конкретными требованиями!

0 голосов
/ 24 июня 2018

Посмотрите пример репо Ричарда Фельдмана на одной странице здесь .По сути, у вас есть приложение верхнего уровня, которое управляет каждой моделью \ просмотром \ обновлением на странице.

...