Несколько дней назад я разработал небольшое личное приложение. Мне нужен был сайт со статической информацией, чтобы помогать пользователям.
Благодаря компоненту "Навигация" от Elm, мы можем легко создавать статические сети.
Необходимые пакеты
- вяз-язык / ядро
- вяз-lang / html
- вяз-язык / дом
- вяз-язык / виртуальный дом
- вяз-язык / навигация
Статический веб-сайт не требует пакета evancz / url-parser.
Elm-package.json может выглядеть так:
Программная функция
Программные функции Navigation немного отличаются от Html-пакета.
Известная нам программная функция выглядит так:
program : { init : (model, Cmd msg) , update : msg -> model -> (model, Cmd msg) , subscriptions : model -> Sub msg , view : model -> Html msg } -> Program Never model msg
Однако программная функция из пакета навигации определяется как:
program : (Location -> msg) -> { init : Location -> (model, Cmd msg) , update : msg -> model -> (model, Cmd msg) , subscriptions: model -> Sub msg , view : model -> Html msg } -> Program Never model msg
Первый аргумент - (Местоположение - ›сообщение). Это преобразует Location в сообщение при изменении URL-адреса. Это сообщение передается в нашу функцию update, как и любое другое.
С другой стороны, функция init принимает в качестве первого аргумента Location. Это позволяет использовать URL-адрес при инициализации.
Модель
В состоянии приложения мы сохраним текущую страницу. Поэтому давайте определим ADT (тип объединения в Elm) для страниц:
type Page = Home | About | Contact
Home, About и Contact - это функции, возвращающие тип страницы. Аннотации типа для функции Home (для примера):
Home : Page
Я определил модель так:
type alias Model = { page : Page }
Если вам нужна дополнительная информация о ADT и типе объединения, вы можете перейти по этой ссылке.
Обновление
Наша функция обновления получает сообщения при каждом изменении URL-адреса через функцию, указанную в функции Navigation.program.
Мы определим эту функцию в типе объединения Msg:
type Msg = UrlChange Navigation.Location
Аннотация типа из UrlChange:
UrlChange : Location -> Msg
Вы должны помнить, что Location принадлежит пакету навигации.
Местоположение - это псевдоним типа, определенный как:
type alias Location = { href : String , host : String , hostname : String , protocol : String , origin : String , port_ : String , pathname : String , search : String , hash : String , username : String , password : String }
В этом примере мы будем использовать только значение хеша. Если вам нужно создать более сложный веб-сайт, вам понадобится evancz / url-parser, чтобы превратить Location во что-то более полезное в вашей функции обновления.
В этом примере функция обновления выглядит так:
update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of UrlChange location -> { model | page = (getPage location.hash) } ! [ Cmd.none ]
getPage - это функция, которая получает хэш и возвращает функцию Page:
getPage : String -> Page getPage hash = case hash of "#home" -> Home "#about" -> About "#contact" -> Contact _ -> Home
Символ «_» предназначен для создания ветвей для всех возможностей, таким образом, «#home», «#about» и «#contact» имеют связанную страницу, а все остальное (включая пустую строку) имеет домашнюю страницу по умолчанию.
Поэтому очень легко определить просмотры для каждой страницы.
Вид
В нашей модели у нас есть поле страницы, которое сообщает нам, на какой странице мы находимся, поэтому мы можем определить функцию просмотра следующим образом:
content : Model -> Html Msg content model = case model.page of Home -> h1 [] [ text "Home page!" ] About -> h1 [] [ text "About page!" ] Contact -> h1 [] [ text "Contact page!" ]
В каждой ветке мы определим содержимое страницы.
Заключительные идеи
Вяз магический и дает вам сверхспособности. Вы можете легко написать свое приложение, и если оно компилируется, то оно работает. Без исключения времени выполнения. Никаких сообщений типа «undefined is not a function».
В этой статье я показал, как легко создать статическую веб-страницу. Этот пример можно сделать сколь угодно сложным.
Вы можете найти весь код в этом репозитории Github.
Если вам это понравилось, нажмите 💚 ниже, чтобы другие люди увидели это здесь, на Medium.