elm 0.18 中的局部更新

Locally scoped updates in elm 0.18

我有一个带有许多页面和路由的 elm 0.18 网络应用程序。在 main.elm 中我定义了我的更新函数。

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        FirstUpdateAction ->
    ...

每个动作都经过这个函数,而且越来越大。是否可以为嵌套在整体结构中的较小模块创建更新函数?

例如,我有一个允许用户更改密码的设置页面。有三个 fields/states(passwordOld、passwordNew、passwordConfirm)具有与 onInputonBlur 事件关联的更新操作。这些状态和操作仅与用户设置页面相关,当用户离开页面时,与模型的其余部分无关。

如何为用户设置设置范围?

您可以将代码分解为独立的子模块,每个子模块都有自己的消息类型、更新和查看功能。

例如,您可以有一个文件 SubmoduleA.elm 如下所示:

module SubmoduleA exposing (Model, Msg, update, view)

type Msg = SubMessageA 
         | SubMessageB

         [..]

type alias model = 
    { fieldA : TypeA
    ,  fieldB : TypeB
    ,  [..]
    }

update msg model = 
  case msg of 
    MessageA -> 
        {model | fieldA = [..] } ! []
    [..]

view model = 
    div [id "submoduleAView"]
        [..]

此模块将像这样连接到您的主程序:

module Main exposing (..)

import SubmoduleA exposing (Model, Msg, update, view)

type Msg = MessageA 
         | MessageB
         | ToSubmoduleA (SubmoduleA.Msg)
         [..]

type alias model = 
    { fieldA : TypeA
    , fieldB : TypeB
    , [..]
    , subModuleA : SubmoduleA.Model
    }

update msg model = 
  case msg of 
    MessageA -> 
        {model | fieldA = [..] } ! []

    [..]

    ToSubmoduleA msg = 
        let (newSubmoduleA, newSubmoduleACmd) = SubmoduleA.update msg (.subModuleA model)
        in { model | subModuleA = newSubmoduleA } ! [Cmd.map ToSubmoduleA newSubmoduleACmd]

view model = 
    div [id "mainView"]
        [ ..
        , Html.map ToSubmoduleA <| SubmoduleA.view (.subModuleA model)
        ]

这样,与您的子模块相关的所有信息和状态都封装在您的子模块中,而您的主更新函数中只有一个案例负责消息的正确路由。