Elm 管道将多个值传递给一个函数

Elm Piping Multiple values to a function

我有一个解码器,目前可以正常工作,但我进行了更新,现在需要将两个值传递给 initFilter 函数,而不是仅仅传递视图。

JSON 有一个新的 "filter" 字符串字段,我想根据该值生成特定类型。

这是新字段的解码器:

filterTypeDecoder : Json.Decode.Decoder FilterType
filterTypeDecoder =
    Json.Decode.string
        |> Json.Decode.andThen
            (\s ->
                case s of
                    "filter1" ->
                        Json.Decode.succeed (DefaultFilter)

                    "edited" ->
                        Json.Decode.succeed (EditedFilter)

                    _ ->
                        Json.Decode.fail ("unknown filter: " ++ s)
            )

这是我解码 testModel 的地方

 TestDecoder.decoder today
        |> Json.Decode.andThen
            (\( tester, errors ) ->
                Json.Decode.succeed testModel
                    |> Pipeline.hardcoded tester
                    |> Pipeline.required "view"
                        (viewDecoder
                            |> Json.Decode.map 
                               (initFilter tester DefaultFilter)
                        )
                    |> Pipeline.hardcoded errors

所以这个,正如它所写的那样,目前有效。问题是,我直接提供 DefaultFilter 而不是解码 "filter" 字段来弄清楚它实际上应该是什么。问题是,我不确定如何通过管道传递多个值。

我的第一个想法是在开始时使用 let 单独解码它来设置 filter 的值,但随后我会解码相同的 JSON 两次,这似乎不正确。

有没有办法将过滤器解码并通过管道传输到我通过管道传输视图的同一位置?如果我不是 100% 清楚,请告诉我...仍然难以理解 elm 解码。

您可以使用 Json.Decode.andThen 根据 JSON 本身的值使用不同的解码器。

首先,让我们将 "view" 的现有解码移动到它自己的函数中以避免多余的缩进:

viewFilterDecoder tester =
    viewDecoder
        |> Json.Decode.map 
           (initFilter tester DefaultFilter)

现在 "view" 的解码看起来像这样:

    |> Pipeline.required "view" (viewFilterDecoder tester)

现在您可以更新 viewFilterDecoder 的定义以首先解码 "filter" 值,然后 (andThen) 在对 initFilter 的后续调用中使用该过滤器值:

viewFilterDecoder tester =
    Json.Decode.field "filter" filterTypeDecoder
        |> Json.Decode.andThen
                (\filter -> viewDecoder
                    |> Json.Decode.map 
                       (initFilter tester filter)
                )