Elm:如何在后续请求中使用来自一个 HTTP 请求的数据
Elm: How to use data from one HTTP request in subsequent requests
我是 Elm 的新手,刚刚阅读了文档 (https://guide.elm-lang.org/)。我正在修改那里的一个例子并四处玩耍。
我想要做的是点击一个端点,它会给我一个 ID 列表。稍后我想用这些 ID 分别访问另一个端点并显示结果。
https://hacker-news.firebaseio.com/v0/topstories.json -
此端点有一个 ID 列表。
https://hacker-news.firebaseio.com/v0/item/[ID].json -
此端点将提供给定 ID 的故事的详细信息。
到目前为止,我可以单独获取所有 ID 的列表,并且可以单独获取每个故事(硬编码 ID)并显示它们。但我在这里想要实现的是
- 从端点 1 获取 ID 列表(其中 500 个)
- 通过到达端点 2 获取前 5 个故事
- 有一个“加载更多”按钮,可以再加载 5 个,依此类推
我不知道该怎么做。非常感谢任何帮助。
谢谢
您可以在处理来自第一个终结点的响应时触发第二个请求。类似于:
type Msg
= GotIds (Result Http.Error (List Int))
| GotStory (Result Http.Error (String))
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
GotIds result ->
case result of
Ok (first::rest) ->
({ model | ids = first::rest }, getStory first)
Ok _ ->
(model, Cmd.none)
Err _ ->
({ model | story = "ERROR"}, Cmd.none)
GotStory result ->
({model | story = Result.withDefault "None" result}, Cmd.none)
如果你想同时触发多个Cmd,你可以使用Cmd.batch
Here is an Ellie 从第一个请求中获取 ID,然后获取第一个 ID 的标题。
您需要为每个 post 创建自定义类型和 decoder。
为了post真实,这里是 Ellie 的所有代码:
module Main exposing (main)
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
import Http
import Json.Decode exposing (Decoder, field, int, list, string )
type alias Model =
{ ids : List Int
, story : String
}
initialModel : Model
initialModel =
{ ids = []
, story = "None"
}
type Msg
= GotIds (Result Http.Error (List Int))
| GotStory (Result Http.Error (String))
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
GotIds result ->
case result of
Ok (first::rest) ->
({ model | ids = first::rest }, getStory first)
Ok [] ->
(model, Cmd.none)
Err _ ->
({ model | story = "ERROR"}, Cmd.none)
GotStory result ->
({model | story = Result.withDefault "None" result}, Cmd.none)
view : Model -> Html Msg
view model =
div []
[ text model.story
]
main : Program () Model Msg
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = (\_ -> Sub.none)
}
init : () -> (Model, Cmd Msg)
init flags =
(initialModel, getIds)
getIds : Cmd Msg
getIds =
Http.get
{ url = "https://hacker-news.firebaseio.com/v0/topstories.json"
, expect = Http.expectJson GotIds (list int)
}
getStory : Int -> Cmd Msg
getStory id =
Http.get
{ url = "https://hacker-news.firebaseio.com/v0/item/" ++ String.fromInt id ++ ".json"
, expect = Http.expectJson GotStory (field "title" string)
}
我是 Elm 的新手,刚刚阅读了文档 (https://guide.elm-lang.org/)。我正在修改那里的一个例子并四处玩耍。 我想要做的是点击一个端点,它会给我一个 ID 列表。稍后我想用这些 ID 分别访问另一个端点并显示结果。
https://hacker-news.firebaseio.com/v0/topstories.json - 此端点有一个 ID 列表。
https://hacker-news.firebaseio.com/v0/item/[ID].json - 此端点将提供给定 ID 的故事的详细信息。
到目前为止,我可以单独获取所有 ID 的列表,并且可以单独获取每个故事(硬编码 ID)并显示它们。但我在这里想要实现的是
- 从端点 1 获取 ID 列表(其中 500 个)
- 通过到达端点 2 获取前 5 个故事
- 有一个“加载更多”按钮,可以再加载 5 个,依此类推
我不知道该怎么做。非常感谢任何帮助。
谢谢
您可以在处理来自第一个终结点的响应时触发第二个请求。类似于:
type Msg
= GotIds (Result Http.Error (List Int))
| GotStory (Result Http.Error (String))
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
GotIds result ->
case result of
Ok (first::rest) ->
({ model | ids = first::rest }, getStory first)
Ok _ ->
(model, Cmd.none)
Err _ ->
({ model | story = "ERROR"}, Cmd.none)
GotStory result ->
({model | story = Result.withDefault "None" result}, Cmd.none)
如果你想同时触发多个Cmd,你可以使用Cmd.batch
Here is an Ellie 从第一个请求中获取 ID,然后获取第一个 ID 的标题。
您需要为每个 post 创建自定义类型和 decoder。
为了post真实,这里是 Ellie 的所有代码:
module Main exposing (main)
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)
import Http
import Json.Decode exposing (Decoder, field, int, list, string )
type alias Model =
{ ids : List Int
, story : String
}
initialModel : Model
initialModel =
{ ids = []
, story = "None"
}
type Msg
= GotIds (Result Http.Error (List Int))
| GotStory (Result Http.Error (String))
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
GotIds result ->
case result of
Ok (first::rest) ->
({ model | ids = first::rest }, getStory first)
Ok [] ->
(model, Cmd.none)
Err _ ->
({ model | story = "ERROR"}, Cmd.none)
GotStory result ->
({model | story = Result.withDefault "None" result}, Cmd.none)
view : Model -> Html Msg
view model =
div []
[ text model.story
]
main : Program () Model Msg
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = (\_ -> Sub.none)
}
init : () -> (Model, Cmd Msg)
init flags =
(initialModel, getIds)
getIds : Cmd Msg
getIds =
Http.get
{ url = "https://hacker-news.firebaseio.com/v0/topstories.json"
, expect = Http.expectJson GotIds (list int)
}
getStory : Int -> Cmd Msg
getStory id =
Http.get
{ url = "https://hacker-news.firebaseio.com/v0/item/" ++ String.fromInt id ++ ".json"
, expect = Http.expectJson GotStory (field "title" string)
}