Elm - 在 Elm 中动态更新字段
Elm - Updating Fields Dynamically in Elm
我复制了这段代码,所以任何人都可以尝试一下http://elm-lang.org/try
import Html exposing (..)
import Html.App as App
import Html.Attributes exposing (..)
import Html.Events exposing (..)
main =
App.program
{ init = init
, view = view
, update = update
, subscriptions = \_ -> Sub.none
}
init =
( { posts = [], newPost = { title = "", slug = "" } }, Cmd.none )
type alias Post =
{ title : String
, slug : String
}
type alias Model =
{ posts : List Post
, newPost : Post
}
type Msg
= NoOp
| NewPostField Post String String
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
NewPostField currentPost field newValue ->
case field of
"title" ->
( { model | newPost = { slug = currentPost.slug, title = newValue } }, Cmd.none )
"slug" ->
( { model | newPost = { slug = newValue, title = currentPost.title } }, Cmd.none )
-- The problem is here, I have to repeat this process for every field
_ ->
( model, Cmd.none )
view model =
div []
[ h1 [] [ text ("title : " ++ model.newPost.title ++ " | slug : " ++ model.newPost.slug) ]
, input [ onInput (NewPostField model.newPost "title"), placeholder "Title" ] []
, input [ onInput (NewPostField model.newPost "slug"), placeholder "Slug" ] []
, button [] [ text "Save" ]
]
我将字段最小化为两个(标题和别名),但还有其他字段,例如:内容、摘录...
有没有什么方法可以在不为所有字段创建案例的情况下更新记录,比如只更新必要的字段而无需遍历所有字段?
我会在您的代码中更改以下内容:
如果每个操作都有特定的消息,您可以拥有更简洁的 update
和 view
功能。编译器还将帮助您检查您是否处理了所有情况,并且您没有传递无意义的参数。
type Msg
= NoOp
| NewPostTitle Post String
| NewPostSlug Post String
这不会为您节省太多打字时间,但您的 update
看起来会像这样。请注意,您不再有嵌套模式匹配。另外,请注意 updating records 的语法,一次一个字段。
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
NewPostTitle currentPost value ->
( { model | newPost = { currentPost | title = value } }, Cmd.none )
NewPostSlug currentPost value ->
( { model | newPost = { currentPost | slug = value } }, Cmd.none )
最后,在您看来,您不必传递字符串参数,这使代码更加简洁。但真正重要的部分是现在它是类型安全的。
view model =
div []
[ h1 [] [ text ("title : " ++ model.newPost.title ++ " | slug : " ++ model.newPost.slug) ]
, input [ onInput (NewPostTitle model.newPost), placeholder "Title" ] []
, input [ onInput (NewPostSlug model.newPost), placeholder "Slug" ] []
, button [] [ text "Save" ]
]
我复制了这段代码,所以任何人都可以尝试一下http://elm-lang.org/try
import Html exposing (..)
import Html.App as App
import Html.Attributes exposing (..)
import Html.Events exposing (..)
main =
App.program
{ init = init
, view = view
, update = update
, subscriptions = \_ -> Sub.none
}
init =
( { posts = [], newPost = { title = "", slug = "" } }, Cmd.none )
type alias Post =
{ title : String
, slug : String
}
type alias Model =
{ posts : List Post
, newPost : Post
}
type Msg
= NoOp
| NewPostField Post String String
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
NewPostField currentPost field newValue ->
case field of
"title" ->
( { model | newPost = { slug = currentPost.slug, title = newValue } }, Cmd.none )
"slug" ->
( { model | newPost = { slug = newValue, title = currentPost.title } }, Cmd.none )
-- The problem is here, I have to repeat this process for every field
_ ->
( model, Cmd.none )
view model =
div []
[ h1 [] [ text ("title : " ++ model.newPost.title ++ " | slug : " ++ model.newPost.slug) ]
, input [ onInput (NewPostField model.newPost "title"), placeholder "Title" ] []
, input [ onInput (NewPostField model.newPost "slug"), placeholder "Slug" ] []
, button [] [ text "Save" ]
]
我将字段最小化为两个(标题和别名),但还有其他字段,例如:内容、摘录...
有没有什么方法可以在不为所有字段创建案例的情况下更新记录,比如只更新必要的字段而无需遍历所有字段?
我会在您的代码中更改以下内容:
如果每个操作都有特定的消息,您可以拥有更简洁的 update
和 view
功能。编译器还将帮助您检查您是否处理了所有情况,并且您没有传递无意义的参数。
type Msg
= NoOp
| NewPostTitle Post String
| NewPostSlug Post String
这不会为您节省太多打字时间,但您的 update
看起来会像这样。请注意,您不再有嵌套模式匹配。另外,请注意 updating records 的语法,一次一个字段。
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
NewPostTitle currentPost value ->
( { model | newPost = { currentPost | title = value } }, Cmd.none )
NewPostSlug currentPost value ->
( { model | newPost = { currentPost | slug = value } }, Cmd.none )
最后,在您看来,您不必传递字符串参数,这使代码更加简洁。但真正重要的部分是现在它是类型安全的。
view model =
div []
[ h1 [] [ text ("title : " ++ model.newPost.title ++ " | slug : " ++ model.newPost.slug) ]
, input [ onInput (NewPostTitle model.newPost), placeholder "Title" ] []
, input [ onInput (NewPostSlug model.newPost), placeholder "Slug" ] []
, button [] [ text "Save" ]
]