在Elm navigation tutorial的基础上,我需要执行一个命令,以便在导航到我的CategoryRoute
后获取其他数据。
我的View.elm
看起来像这样:
view : Model -> Html Msg
view model =
div []
[ page model ]
page : Model -> Html Msg
page model =
case model.categories of
RemoteData.Success categories ->
case model.currentRoute of
CategoryListRoute ->
CategoryList.view categories
CategoryRoute id ->
let maybeCategory =
categories
|> SubCategories
|> flatten
|> filter (\category -> category.id == id)
|> head
_ = update (OnCategorySelected id) model
in
case maybeCategory of
Just category ->
Category.view category
Nothing ->
notFound
当update
更改为OnCategorySelected
时,您会注意到我正在使用currentRoute
消息呼叫CategoryRoute
。
我的Update.eml
看起来像这样:
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
OnArticlesFetch response ->
let
_ = log "got response" response
in
( { model | articles = response }, Cmd.none)
OnLocationChange location ->
let
newRoute =
parseLocation location
in
( { model | currentRoute = newRoute }, Cmd.none )
OnCategorySelected id ->
( model, (getArticles model.tenant id) )
最后,我的Commands.eml
看起来像这样:
getArticles : String -> String -> Cmd Msg
getArticles tenant id =
let
url =
"https://" ++ tenant ++ ".my.api"
_ = log "getArticles for " id
in
Http.post url (Http.jsonBody (encoder id)) decoder
|> RemoteData.sendRequest
|> Cmd.map OnArticlesFetch
我期待一旦我打电话给update OnCategorySelected
,它就会调用getArticles
函数,该函数会传递Cmd Msg
,我原以为会被调用一旦回应进来。
我遇到的问题是,虽然update OnCategorySelected
和getArticles
似乎被调用(如日志打印输出log "getArticles for " id
所示),但我看不到传出的HTTP调用,没有错误,没有结果,也没有log "got response" response
打印输出。
我很困惑我在这里做错了什么,以及在导航到榆树页面时实际获取更多数据的模式...
答案 0 :(得分:4)
榆树是一种纯粹的语言,其副作用被降级为框架。调用更新函数实际上并不执行任何工作。它只返回一个值,该值可以传递给Elm框架,指示它与外部世界进行交互。这意味着当您从page
函数中调用update并丢弃结果时,没有任何反应。
可能导致混淆的一件事是Debug.log
实际上被调用并打印到控制台,这违反了上述语言的纯度。它只是一个神奇的功能,仅用于调试,所以希望它不会引起太多混乱。
在解析RemoteData.Success
案例中的路由并返回包含OnLocationChange
结果Cmd的结果后,您应该在更新函数中处理getArticles
个案。
OnLocationChange location ->
let
newRoute =
parseLocation location
cmd =
case newRoute of
CategoryRoute id ->
getArticles model.tenant id
_ ->
Cmd.none
in
( { model | currentRoute = newRoute }, cmd )