首先 - 你的decoder
功能稍微關閉。沒有中間的「屬性」的對象,所以你可以把它改成這樣:
decoder : Decoder Job
decoder =
Decode.object3 Job
("task" := Decode.string)
("who" := Decode.string)
("place" := Decode.string)
你是正確的,你需要的elm-http包。使用此功能,您可以創建一個將結果映射到操作的Http.get
任務。
作爲一個基本的例子,讓我們製作一個按鈕,從網址中下拉作業列表。我們需要一個GetJobs
操作來觸發HTTP請求,以及一個ShowJobs
操作,當請求成功返回時將觸發該操作。
假設我們的操作類型如下:
type Action
= NoOp
| GetJobs
| ShowJobs (Maybe Jobs)
然後,我們可以創建一個getJobs
函數,建立可運行的任務。對於這個簡單的例子,我們可以使用Task.toMaybe
來抑制任何HTTP或JSON解碼錯誤。
getJobs : Effects Action
getJobs =
Http.get decoderColl jobsUrl
|> Task.toMaybe
|> Task.map ShowJobs
|> Effects.task
爲了膠水都在一起,我們將使用StartApp因爲它可以讓我們用任務和作用。假設jobs.json存在於同一個目錄中,這是一個可以在本地構建的工作示例。
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)
由於某些原因,當我嘗試編譯代碼時,它的內存不足,從來沒有這樣做過。 – Stanko
發現問題,我需要將'({model | jobs = Nothing},getJobs)'改爲'({model | jobs < - Nothing},getJobs)'。 '='和'<-'有什麼區別? – Stanko
最近在版本0.16中,<-'在該上下文中被更改爲「=」。聽起來像你只需要最新版本的elm –