榆树:连续发出网络请求

时间:2016-07-07 23:47:21

标签: elm

我正在努力学习过去一周的榆树,并希望通过致电官方Hacker News API建立一个简单的黑客新闻客户端。

我正在调用https://hacker-news.firebaseio.com/v0/topstories.json来获取可以返回故事ID数组的热门故事。一旦我有了ID,我需要随后调用https://hacker-news.firebaseio.com/v0/item/ [/ * Id在这里* /]。json获取每个故事项目的详细信息。

我有一个Main.elm文件,可以获取热门新闻列表。

type Msg = Request 
  | RequestSuccess (List Int) 
  | RequestFail Http.Error


update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
 case msg of
  Request ->
   (model, getTopNews)
  RequestSuccess list->
   (Model list, Cmd.none)
  RequestFail error->
   (Model [], Cmd.none)

下一部分是我感到困惑的地方,为每个返回的项目提取详细信息。我还有一个NewsItem组件来显示每个新闻项的详细信息。

如何通过在NewsItem组件(子组件)中创建联合类型来获取详细信息来解决这个问题?如果那就是我应该怎么做..

  1. 如果Main.elm内的第一个api调用完成,我怎么能从NewsItem组件调用fetch details api?
  2. 或者我错过了一些明显的东西?这根本不是正确的方法吗?
  3. You can see what I have tried so far here.

1 个答案:

答案 0 :(得分:1)

这是我的建议。它假定您将独立加载每个NewsItem并且它们也可以独立地失败。如果情况并非如此,那么我们肯定会想出一些更适合你的东西。

1)将NewsItem表示为不仅仅是一条记录,而是表示包含在某种类型中的记录,以表示加载详细信息可能会失败的可能性。有关详细信息,请参阅http://blog.jenkster.com/2016/06/how-elm-slays-a-ui-antipattern.html

module NewsItem

-- imports and such

type Model = Loading | Success NewsItem | Failure Http.Error

2)在init模块中写一个NewsItem函数,该模块接受Int并返回(NewsItem.Model, Cmd NewsItem.Msg)

init : Int -> (Model, Cmd Msg)
init newsItemId =
    ( Loading
    , getNewsItem newsItemId |> Task.perform GetItemFailure GetItemSuccess
    )

3)在Main模块中,获取ID列表后,使用List (NewsItem.Model, Cmd NewsItem.Msg)函数将其映射到init,并使用Elm架构的技术将它们存储为父模型中的子项。我建议将它们存储为Dict Int NewsItem.Model,将ID映射到子模型。

RequestSuccess list ->
    let
        children =
            list |> List.map (\id -> (id, NewsItem.init id))

        childModels =
            children
                |> List.map (\(id, (model, cmd)) -> (id, model))
                |> Dict.fromList

        childCmds =
            children
                |> List.map (\(id, (model, cmd)) -> Cmd.map (NewsItemMsg id) cmd)
                |> Cmd.batch
    in
        (Model childModels, childCmds)