调用更新后未调用命令
Command not being invoked after calling update
在 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
您会注意到,当 currentRoute
更改为 CategoryRoute
时,我自己用 OnCategorySelected
消息调用 update
。
我的 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
打印输出。
我很困惑我在这里做错了什么,以及在导航到 Elm 中的页面时实际获取更多数据的模式是什么...
Elm 是一种纯语言,其中的副作用归属于框架。调用更新函数本身实际上并不执行任何工作。它只是 returns 一个可以传递给 Elm 框架的值,指示它与外界交互。这意味着当您从 page
函数中调用更新并丢弃结果时,什么也不会发生。
可能会造成混淆的一件事是 Debug.log
实际上确实被调用并打印到控制台,这违反了上述语言的纯度。这只是一个神奇的功能,只为调试而存在,所以希望它不会造成太多混乱。
在 OnLocationChange
案例中解析路由并返回包含 getArticles
结果 Cmd 的结果后,您应该在更新函数中处理 RemoteData.Success
案例。
OnLocationChange location ->
let
newRoute =
parseLocation location
cmd =
case newRoute of
CategoryRoute id ->
getArticles model.tenant id
_ ->
Cmd.none
in
( { model | currentRoute = newRoute }, cmd )
在 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
您会注意到,当 currentRoute
更改为 CategoryRoute
时,我自己用 OnCategorySelected
消息调用 update
。
我的 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
打印输出。
我很困惑我在这里做错了什么,以及在导航到 Elm 中的页面时实际获取更多数据的模式是什么...
Elm 是一种纯语言,其中的副作用归属于框架。调用更新函数本身实际上并不执行任何工作。它只是 returns 一个可以传递给 Elm 框架的值,指示它与外界交互。这意味着当您从 page
函数中调用更新并丢弃结果时,什么也不会发生。
可能会造成混淆的一件事是 Debug.log
实际上确实被调用并打印到控制台,这违反了上述语言的纯度。这只是一个神奇的功能,只为调试而存在,所以希望它不会造成太多混乱。
在 OnLocationChange
案例中解析路由并返回包含 getArticles
结果 Cmd 的结果后,您应该在更新函数中处理 RemoteData.Success
案例。
OnLocationChange location ->
let
newRoute =
parseLocation location
cmd =
case newRoute of
CategoryRoute id ->
getArticles model.tenant id
_ ->
Cmd.none
in
( { model | currentRoute = newRoute }, cmd )