在我的Elm程序中,我想根据查询字符串初始化我的模型。
例如,如果查询字符串为?w=3&h=5
,我希望:
initialModel =
{ width = 3
, height = 5
}
可以在Elm中实现这一点,或者这样做的唯一方法是在Javascript中获取查询参数并通过端口传递它们吗?
答案 0 :(得分:8)
没有内置的核心库方式来访问URL。您可以使用端口和社区库jessitron/elm-param-parsing。
如果您还想设置网址,可以再次使用端口,也可以使用历史记录API,TheSeamau5/elm-history中有绑定。
答案 1 :(得分:6)
以下示例对榆木0.18使用evancz/url-parser
和elm-lang/navigation
。对于Elm 0.19,概念是相同的,因为这两个软件包都已移动并重新标记为官方elm/url
和elm/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更改时调用的函数。
(我知道这是一个老问题,但当我在寻找相同问题的解决方案并且接受的答案没有帮助时,这个链接突然出现)