Есть ли в elm шаблон, позволяющий избежать написания большого количества сообщений только для обновления отдельных полей дочерних элементов вашей модели?
В настоящее время я заканчиваю с кодом, как показано ниже, с сообщением для каждого изменяемого входа и затем с кучей логики обновления для каждого поля. То, что я хотел бы сделать, это иметь сообщение типа AChanged, которое обрабатывает все изменения в любом свойстве A. Либо путем обновления записи в функции, которая генерирует сообщение, либо путем передачи имени поля и последующего использования его для непосредственного выполнения обновите запись, как вы могли бы в Javascript.
module Main exposing (Model)
import Browser exposing (Document, UrlRequest)
import Browser.Navigation as Nav exposing (Key)
import Html exposing (div, input)
import Html.Events exposing (onInput)
import Url exposing (Url)
type alias A =
{ a : String
, b : String
, c : String
, d : String
}
type alias B =
{ e : String
, f : String
, g : String
, h : String
}
type alias Model =
{ key : Nav.Key
, url : Url.Url
, a : A
, b : B
}
type Msg
= UrlChanged Url.Url
| LinkClicked Browser.UrlRequest
| AaChanged String
| AbChanged String
| AcChanged String
| AdChanged String
| BeChanged String
| BfChanged String
| BgChanged String
| BhChanged String
init : () -> Url.Url -> Nav.Key -> ( Model, Cmd Msg )
init flag url key =
( Model key url (A "" "" "" "") (B "" "" "" ""), Cmd.none )
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.none
view : Model -> Document msg
view model =
{ title = "Mister Mandarin"
, body =
div
[ input [ onInput AaChanged ] []
, input [ onInput AbChanged ] []
, input [ onInput AcChanged ] []
, input [ onInput AdChanged ] []
, input [ onInput BeChanged ] []
, input [ onInput BfChanged ] []
, input [ onInput BgChanged ] []
, input [ onInput BhChanged ] []
]
[]
}
update : Msg -> Model -> ( Model, Cmd msg )
update msg model =
case msg of
LinkClicked urlRequest ->
case urlRequest of
Browser.Internal url ->
( model, Nav.pushUrl model.key (Url.toString url) )
Browser.External href ->
( model, Nav.load href )
UrlChanged url ->
( { model | url = url }
, Cmd.none
)
AaChanged value ->
let
a =
model.a
newA =
{ a | a = value }
in
( { model | a = newA }, Cmd.none )
AbChanged value ->
let
a =
model.a
newA =
{ a | b = value }
in
( { model | a = newA }, Cmd.none )
AcChanged value ->
let
a =
model.a
newA =
{ a | c = value }
in
( { model | a = newA }, Cmd.none )
AdChanged value ->
let
a =
model.a
newA =
{ a | d = value }
in
( { model | a = newA }, Cmd.none )
BeChanged value ->
let
b =
model.b
newB =
{ b | e = value }
in
( { model | b = newB }, Cmd.none )
BfChanged value ->
let
b =
model.b
newB =
{ b | f = value }
in
( { model | b = newB }, Cmd.none )
BgChanged value ->
let
b =
model.b
newB =
{ b | g = value }
in
( { model | b = newB }, Cmd.none )
BhChanged value ->
let
b =
model.b
newB =
{ b | h = value }
in
( { model | b = newB }, Cmd.none )
main : Program () Model Msg
main =
Browser.application
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
, onUrlChange = UrlChanged
, onUrlRequest = LinkClicked
}