Zunächst einmal - Ihre decoder
Funktion ist etwas aus. Es gibt keine Zwischen „Attribute“ Objekt, so können Sie es auf diese ändern:
decoder : Decoder Job
decoder =
Decode.object3 Job
("task" := Decode.string)
("who" := Decode.string)
("place" := Decode.string)
Sie sind richtig, dass Sie die elm-http Paket benötigen. Damit können Sie eine Http.get
Aufgabe erstellen, die das Ergebnis einer Aktion zuordnet.
Als ein grundlegendes Beispiel, machen wir eine Schaltfläche, die die Liste der Aufträge von einer URL herunterzieht. Wir benötigen eine GetJobs
Aktion, um die HTTP-Anfrage auszulösen, und eine ShowJobs
Aktion, die ausgelöst wird, wenn die Anfrage erfolgreich zurückkommt.
Art unsere Aktion Unter der Annahme, sieht wie folgt aus:
type Action
= NoOp
| GetJobs
| ShowJobs (Maybe Jobs)
Dann können wir eine getJobs
Funktion erstellen, die eine Aufgabe erstellt, die ausgeführt werden können. In diesem einfachen Beispiel können wir Task.toMaybe
verwenden, um HTTP- oder JSON-Decodierungsfehler zu unterdrücken.
getJobs : Effects Action
getJobs =
Http.get decoderColl jobsUrl
|> Task.toMaybe
|> Task.map ShowJobs
|> Effects.task
Um sie alle zusammen zu kleben, werden wir StartApp verwenden, da es uns Aufgaben und Effekte nutzen können. Hier ist ein Arbeitsbeispiel, das Sie lokal erstellen können, vorausgesetzt, dass jobs.json in demselben Verzeichnis vorhanden ist.
import Http
import StartApp
import Effects exposing (Effects,Never)
import Task
import Html exposing (..)
import Html.Events exposing (..)
import Json.Decode as Decode exposing (Decoder, (:=))
jobsUrl = "./jobs.json"
-- StartApp plumbing
app =
StartApp.start { init = init, view = view, update = update, inputs = [] }
main =
app.html
port tasks : Signal (Task.Task Never())
port tasks =
app.tasks
type Action
= NoOp
| GetJobs
| ShowJobs (Maybe Jobs)
type alias Model =
{ jobs : Maybe Jobs }
init =
({ jobs = Nothing }, Effects.none)
update action model =
case action of
NoOp ->
(model, Effects.none)
GetJobs ->
({ model | jobs = Nothing }, getJobs)
ShowJobs maybeJobs ->
({ model | jobs = maybeJobs }, Effects.none)
view address model =
div []
[ button [ onClick address GetJobs ] [ text "Click to get jobs!" ]
, viewJobs model.jobs
]
viewJobs maybeJobs =
let
viewJob job =
li [] [ text ("Task: " ++ job.task ++ "; Who: " ++ job.who ++ "; Place: " ++ job.place) ]
in
case maybeJobs of
Nothing ->
div [] [ text "No jobs to display. Try clicking the button" ]
Just jobs ->
ul [] (List.map viewJob jobs)
-- This is the key to map the result of the HTTP GET to an Action
-- Note: Task.toMaybe swallows any HTTP or JSON decoding errors
getJobs : Effects Action
getJobs =
Http.get decoderColl jobsUrl
|> Task.toMaybe
|> Task.map ShowJobs
|> Effects.task
-- An alternative to Task.toMaybe which dumps error information to the console log
toMaybeWithLogging : Task.Task x a -> Task.Task y (Maybe a)
toMaybeWithLogging task =
Task.map Just task `Task.onError` (\msg -> Debug.log (toString msg) (Task.succeed Nothing))
-- The Job type aliases from the question
type alias Job = {
task : String
, who : String
, place: String
}
type alias Jobs = List Job
-- The updated Job decoder
decoder : Decoder Job
decoder =
Decode.object3 Job
("task" := Decode.string)
("who" := Decode.string)
("place" := Decode.string)
decoderColl : Decoder Jobs
decoderColl =
Decode.object1 identity
("jobs" := Decode.list decoder)
Aus irgendeinem Grund, wenn ich versuche, Ihren Code zu kompilieren, läuft es aus dem Speicher, hatte noch nie zuvor. – Stanko
Das Problem gefunden, ich musste '({model | jobs = Nothing}, getJobs) '' '({model | jobs <- Nothing}, getJobs)' 'ändern. Was ist der Unterschied zwischen '=' und '<-'? – Stanko
'<-' wurde kürzlich in Version 0.16 zu' = 'in diesem Zusammenhang geändert. Klingt wie du brauchst nur die neueste Version von Ulme –