在 Elm 0.19.1 中,是否可以在解码器中对初始模型发出 http-get 请求?

TBa*_*ist 5 elm

我在 Elm 中创建了一个组件,用户可以在其中创建不同条件的列表。对于此组件,用户应该能够创建搜索联系人的条件。这些联系人将显示在不同的(非 Elm)页面上。如果用户返回到标准构建器,则应再次显示之前填写的标准。

为此,我使用用于在 Elm 中创建查询的 JSON。应该对其进行解码以创建将显示用户之前所做的输入的对象。

我使用的对象之一是列表。该列表包含带有 id 和 name 的元组。对于查询生成器,我仅将 JSON 中对象的 id 发送到后端。这意味着,如果用户返回标准构建器,解码器只能解码 id 列表。对于我的列表选择,我还想获取具有 id 的对象的名称。

现在这就是我遇到一些问题的地方。要发出 http 请求,我必须使用Cmd.Msg. 在更新功能中,我必须更新我的模型。问题是,我还没有模型,因为我仍在解码我的初始模型。另外,我想Decoder在 a (对于我的初始模型)中使用 a (对于 http 请求的结果)Decoder并不是最好的主意。

Decoder有没有办法解决我在初始模型中发出 http 请求的问题?

bdu*_*kes 5

这里有几个选项,具体取决于您的情况的复杂程度。最终,init生成一个(Model, Cmd Msg)值,并且您的 HTTP 请求可以成为该值的一部分Cmd

选项1:根据解码后的模型生成HTTP请求

init : Decode.Value -> (Model, Cmd Msg)
init json =
    let
        initialRequests model =
            List.map initialRequest model.items
    in
    case Decode.decodeValue flagsDecoder json of
        Ok model ->
            ( model, initialRequests model |> Cmd.batch )

        Err _ ->
            ( initialModel, Cmd.none )

Run Code Online (Sandbox Code Playgroud)

选项 2:解码时生成 HTTP 请求

init : Decode.Value -> ( Model, Cmd Msg )
init json =
    let
        flagsDecoder =
            Decode.map (\items -> ({ items = List.map Tuple.first items }, List.map Tuple.second items))
                (Decode.field "items" (Decode.list itemDecoder))
        itemDecoder =
            Decode.field "name" Decode.string
                |> Decode.map (\name -> (name, initialRequest name))
    in
    case Decode.decodeValue flagsDecoder json of
        Ok ( model, cmds ) ->
            ( model, cmds |> Cmd.batch )

        Err _ ->
            ( initialModel, Cmd.none )
Run Code Online (Sandbox Code Playgroud)

您的init函数需要能够返回一个Model“不完整”的值,等待这些响应返回。有时,这就像将您等待的值建模为Maybe值一样简单,有时您可能希望将模型的很大一部分包装在一个值中,以指示它是否有效。

type Model
    = Initializing String (Maybe Thing1) (Maybe Thing2)
    | Ready { baseUrl : String, thing1 : Thing1, thing2 : Thing2 }
Run Code Online (Sandbox Code Playgroud)