You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用update后命令未触发:Elm导航路由数据获取问题

How to Trigger Data Fetch Commands When Navigating to CategoryRoute in Elm

Hey there! Let's break down how to handle fetching extra data when navigating to your CategoryRoute in Elm. The key thing to remember is that commands (like data fetches) should be dispatched from your update function, not the view—since the view is just for rendering based on the current model state.

Here's a step-by-step approach tailored to your setup:

1. Add Messages for Data Fetching

First, extend your Msg type to handle initiating the fetch and processing the result:

type Msg
    = OnLocationChange Location
    | UrlChanged Url
    -- Add these two messages to manage extra data fetching
    | FetchCategoryExtraData String
    | CategoryExtraDataFetched (RemoteData.WebData ExtraData)
    -- ... keep your existing messages

Replace ExtraData with whatever custom type you're using for the additional category details.

2. Update Your Model to Store Extra Data

Add a field to your Model to track the state of the extra data fetch (loading, success, failure, etc.):

type alias Model =
    { currentRoute : Route
    , categories : RemoteData.WebData (List Category)
    -- Add this line to hold extra category data
    , categoryExtraData : RemoteData.WebData ExtraData
    -- ... keep your existing fields
    }

Initialize this field with RemoteData.NotAsked in your initial model setup.

3. Trigger the Fetch When Route Changes

In your update function, catch the route change event and dispatch the fetch command if the new route is CategoryRoute:

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
    case msg of
        OnLocationChange location ->
            let
                newRoute = parseLocation location
                -- Dispatch fetch command only when navigating to CategoryRoute
                fetchCmd =
                    case newRoute of
                        CategoryRoute categoryId ->
                            -- Replace with your actual API fetch logic
                            Http.get
                                { url = "/api/categories/" ++ categoryId ++ "/extra"
                                , expect = RemoteData.expectJson CategoryExtraDataFetched extraDataDecoder
                                }
                        _ ->
                            Cmd.none
            in
            ( { model | currentRoute = newRoute }, fetchCmd )

        -- Update model when extra data fetch completes
        CategoryExtraDataFetched result ->
            ( { model | categoryExtraData = result }, Cmd.none )

        -- ... handle your other existing messages

This ensures the fetch starts immediately when the user navigates to a category route.

4. Adjust the View to Use the Extra Data

Update your page function to render based on both the category data and the fetched extra data state:

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 |> List.filter (\cat -> cat.id == id) |> List.head
                    in
                    -- Check both category existence and extra data state
                    case (maybeCategory, model.categoryExtraData) of
                        (Just category, RemoteData.Success extraData) ->
                            -- Render full category view with extra data
                            CategoryDetail.view category extraData

                        (Just category, RemoteData.Loading) ->
                            div [] [ text "Loading extra details..." ]

                        (Just category, RemoteData.Failure err) ->
                            div [] [ text ("Oops, failed to load extra details: " ++ Debug.toString err) ]

                        (Nothing, _) ->
                            div [] [ text "Category not found" ]

        RemoteData.Loading ->
            div [] [ text "Loading categories..." ]

        RemoteData.Failure err ->
            div [] [ text ("Failed to load categories: " ++ Debug.toString err) ]

        RemoteData.NotAsked ->
            div [] [ text "Initializing..." ]

Quick Tips:

  • If users navigate between multiple categories often, consider using a Dict String (RemoteData.WebData ExtraData) instead of a single categoryExtraData field—this lets you cache data for previously viewed categories and avoid redundant fetches.
  • Double-check that your parseLocation function correctly maps URLs to the CategoryRoute id variant (as set up in the Elm navigation tutorial).

That should do it! Now when users navigate to a category route, your app will automatically fetch the required extra data and update the view once it's ready.

内容的提问来源于stack exchange,提问作者ronif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:49:58