Skip to content

Instantly share code, notes, and snippets.

@yuizho
Created January 5, 2019 13:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yuizho/c0b08ee59d3da81891426b17209fff4d to your computer and use it in GitHub Desktop.
Save yuizho/c0b08ee59d3da81891426b17209fff4d to your computer and use it in GitHub Desktop.
Elmのナビゲーションサンプルコード
module Main exposing (Model, Msg(..), init, main, subscriptions, update, view, viewLink)
import Browser
import Browser.Navigation as Nav
import Html exposing (..)
import Html.Attributes exposing (..)
import Url
import Url.Parser exposing ((</>), Parser, int, map, oneOf, parse, s, string)
-- MAIN
main : Program () Model Msg
main =
Browser.application
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
, onUrlChange = UrlChanged
, onUrlRequest = LinkClicked
}
-- MODEL
type alias Model =
{ key : Nav.Key
, url : Url.Url
, route : Route
}
init : () -> Url.Url -> Nav.Key -> ( Model, Cmd Msg )
init flags url key =
( Model key url TopPage, Cmd.none )
-- URL PARSER
type Route
= TopPage
| NextPage String
routeParser : Parser (Route -> a) a
routeParser =
oneOf
[ map NextPage (s "next" </> string)
]
parseUrl : Url.Url -> Route
parseUrl url =
let
parsed =
-- #をパースするためにUrlをparseする前にfragmentの設定してる
-- https://package.elm-lang.org/packages/elm/url/1.0.0/Url
-- 以下の実装を参考にした
-- https://github.com/rtfeldman/elm-spa-example/blob/b5064c6ef0fde3395a7299f238acf68f93e71d03/src/Route.elm#L59
{ url | path = Maybe.withDefault "" url.fragment, fragment = Nothing }
|> parse routeParser
in
case parsed of
Just route ->
route
Nothing ->
TopPage
-- UPDATE
type Msg
= LinkClicked Browser.UrlRequest
| UrlChanged Url.Url
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
LinkClicked urlRequest ->
case urlRequest of
Browser.Internal url ->
( model, Nav.pushUrl model.key (Url.toString url) )
Browser.External href ->
( model, Nav.load href )
UrlChanged url ->
let
-- Urlが変更されたら、parseUrlでRoute型variantsへ変換
route =
parseUrl url
in
( { model | url = url, route = route }
, Cmd.none
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.none
-- VIEW
view : Model -> Browser.Document Msg
view model =
case model.route of
TopPage ->
{ title = "URL Interceptor"
, body =
let
contentPath =
"/#/next/"
in
[ text "The current URL is: "
, b [] [ text (Url.toString model.url) ]
, ul []
[ viewLink <| contentPath ++ "foo"
, viewLink <| contentPath ++ "bar"
]
]
}
NextPage param ->
{ title = "URL Interceptor"
, body =
[ text param ]
}
viewLink : String -> Html msg
viewLink path =
li [] [ a [ href path ] [ text path ] ]
@yuizho
Copy link
Author

yuizho commented Jan 5, 2019

公式ガイドのナビゲーションのサンプルコードに画面遷移を加えた感じのものになります。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment