2016-10-20 126 views
1

更新域动态我复制此代码,所以任何人都可以尝试一下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" ] 
    ] 

我最小下地两(标题和蛞蝓),但也有其他人一样:内容,摘录。 ..

是否有反正我可以更新记录而不创建所有字段的情况下,像只更新必要的字段,而不通过所有的字段?

回答

4

我会改变以后的事在你的代码:

如果你对每个动作的具体信息,你可以有更清洁updateview功能。编译器还会帮助你检查你是否处理了所有的情况,并且你没有通过一个毫无意义的论点。

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" ] 
    ] 
+0

是的,我这样做,首先,我在寻找更有效的方式,而不是每个字段的功能更新,(我有一些车型谁不超过12个字段) – kayne

+0

我喜欢这个答案Elm记录是一种静态类型。如果我想要有动态的东西,那么我会使用'Dict'或其他东西。 – Tosh

+0

谢谢你们,我认为这是榆树的方式,写得太多了,我会坚持下去 – kayne