如何在 Elm 中获取查询参数?

How to get query parameters in Elm?

在我的 Elm 程序中,我想根据查询字符串初始化我的模型。

例如,如果查询字符串是 ?w=3&h=5 我想要:

initialModel =
  { width = 3
  , height = 5
  }

是否可以在 Elm 中实现此目的,或者唯一的方法是在 Javascript 中获取查询参数并通过端口传递它们?

没有内置核心库的方式来访问URL。您可以使用端口和社区库 jessitron/elm-param-parsing.

如果您还想设置 URL,您可以再次使用端口,或者您可以使用历史记录 API,在 TheSeamau5/elm-history 中有绑定。

遗憾的是 jessitron/elm-param-parsing 不适用于 Elm 0.18。

使用elm-lang/navigation包:

http://package.elm-lang.org/packages/elm-lang/navigation/latest/Navigation

https://github.com/elm-lang/navigation/tree/2.1.0

尤其是这个函数:

program
    : (Location -> msg)
    -> { init : Location -> (model, Cmd msg), update : msg -> model -> (model, Cmd msg), view : model -> Html msg, subscriptions : model -> Sub msg }
    -> Program Never model msg

在第二个参数中可以看到"init : Location -> (model, Cmd msg)"。这应该处理初始 URL 的读取。作为补充,第一个参数是一个函数,每次 URL 更改时都会调用该函数。

(我知道这是一个老问题,但是这个 link 在我寻找相同问题的解决方案时突然出现并且接受的答案没有帮助)

榆木 0.19


对于 elm 0.19,下面的概念是相同的。这两个软件包仍然存在,但已被移动并重新标记为官方 elm/url and elm/browser 库。

榆木 0.18


本示例使用 evancz/url-parser and elm-lang/navigation。文档中有一些不直接的问题,但我在下面简要解释了它们。这个例子应该不言自明。

module Main exposing (..)

import Html as H exposing (..)
import Navigation exposing (Location)
import UrlParser as UP exposing ((</>), (<?>), top, parsePath, oneOf, s, stringParam, Parser)
import Maybe.Extra as MaybeExtra exposing (unwrap)


type Route
    = UrlRoute (Maybe String) (Maybe String)
    | NotFoundRoute


type Msg
    = UrlParser Navigation.Location


type alias Model =
    { location : Route
    , w : String
    , h : String
    }


type alias SearchParams =
    { w : Maybe String, h : Maybe String }


main =
    Navigation.program UrlParser
        { init = init
        , view = view
        , update = update
        , subscriptions = (\_ -> Sub.none)
        }


init : Location -> ( Model, Cmd Msg )
init location =
    let
        currentPath =
            parseLocation location
    in
        ( initialModel currentPath
        , Cmd.none
        )


parseLocation : Location -> Route
parseLocation location =
    case (parsePath matchers location) of
        Just route ->
            route

        Nothing ->
            NotFoundRoute


matchers : Parser (Route -> a) a
matchers =
    UP.map UrlRoute (UP.s "index" <?> UP.stringParam "w" <?> UP.stringParam "h")


initialModel : Route -> Model
initialModel route =
    { location = route
    , w = MaybeExtra.unwrap "" (\x -> Maybe.withDefault "" x.w) (parseParams route)
    , h = MaybeExtra.unwrap "" (\x -> Maybe.withDefault "" x.h) (parseParams route)
    }


parseParams : Route -> Maybe SearchParams
parseParams route =
    case route of
        UrlRoute w h ->
            Just { w = w, h = h }

        NotFoundRoute ->
            Nothing


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        UrlParser location ->
            ( model
            , Cmd.none
            )


view : Model -> Html msg
view model =
    div []
        [ h1 [] [ text "URL Info" ]
        , div [] [ text ("W is: " ++ model.w) ]
        , div [] [ text ("H is: " ++ model.h) ]
        ]

"trick" 是创建另一个类型别名来放置您的查询参数。在上面的示例中,我创建了 SearchParams 类型。创建此类型后,我们只需使用一个 initialModel 接受 currentPath.

从那里,我们的模型可以使用 Maybe.withDefault 提取查询参数(它需要是 Maybe 类型,因为参数可能不存在)。一旦我们在模型中有了数据,我们就在视图中打印出来。

希望对您有所帮助!