我正在努力学习过去一周的榆树,并希望通过致电官方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组件(子组件)中创建联合类型来获取详细信息来解决这个问题?如果那就是我应该怎么做..
答案 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)