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

时间:2015-11-06 07:03:25

标签: elm

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

例如,如果查询字符串为?w=3&h=5,我希望:

initialModel =
  { width = 3
  , height = 5
  }

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

3 个答案:

答案 0 :(得分:8)

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

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

答案 1 :(得分:6)

以下示例对榆木0.18使用evancz/url-parserelm-lang/navigation。对于Elm 0.19,概念是相同的,因为这两个软件包都已移动并重新标记为官方elm/urlelm/browser库。

在文档中有一些不容易理解的地方,但是我在下面简要地解释了它们。这个例子应该说明一切。

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) ]
        ]

“技巧”是创建另一个类型别名,以将查询参数置于其中。在上面的示例中,我创建了类型SearchParams。创建此类型后,我们只需使用一个initialModel的{​​{1}}。

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

希望这会有所帮助!

答案 2 :(得分:2)

不幸的是,jessitron / elm-param-parsing不适用于Elm 0.18。

使用elm-lang /导航包:

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 - &gt;(model,Cmd msg)”。这应该处理初始URL的读取。为了补充这一点,第一个参数是每次URL更改时调用的函数。

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