2016-10-20 4 views
1

kopiert ich diesen Code, so dass jeder es ausprobieren kann http://elm-lang.org/tryElm - Aktualisierung Felder dynamisch in Elm

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

I minimiert, die Felder zu zwei (Titel und Wegschnecke), aber es gibt andere wie: Inhalt, Auszug. ..

Gibt es trotzdem, ich kann den Datensatz aktualisieren, ohne einen Fall für alle Felder zu erstellen, etwas wie die Aktualisierung nur das Feld notwendig, ohne durch alle von ihnen zu gehen?

Antwort

4

würde ich das Folgende in Ihrem Code ändern:

Wenn Sie eine bestimmte Nachricht für jede Aktion haben, können Sie viel sauberer update und view Funktionen haben. Der Compiler hilft Ihnen auch zu überprüfen, dass Sie alle Fälle behandeln und kein bedeutungsloses Argument übergeben.

type Msg 
    = NoOp 
    | NewPostTitle Post String 
    | NewPostSlug Post String 

Dies macht Sie zu viel Tipp nicht retten, aber Ihre update wie folgt aussehen. Beachten Sie, dass Sie keine geschachtelte Mustererkennung mehr haben. Beachten Sie auch die Syntax für updating records, jeweils ein Feld.

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) 

Schließlich müssen Sie in Ihrer Ansicht nicht den String-Parameter übergeben, was den Code ein wenig prägnanter macht. Aber der wirklich wichtige Teil ist, dass es jetzt typsicher ist.

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

Ja ich dies zunächst tat, ich bin auf der Suche nach effizienteren Weg, anstatt eine Funktion Update für jedes Feld, (ich habe einige Modelle, die mehr als 12 Felder hat) – kayne

+0

Ich mag diese Antwort als Elm-Datensatz ist ein statischer Typ. Wenn ich etwas Dynamisches haben möchte, dann würde ich 'Dict' oder so etwas verwenden. – Tosh

+0

Danke Jungs, ich denke, das ist der Weg in Elm, zu viel schreiben, ich bleibe dabei – kayne