Spec-Zone.ru › Phoenix

LiveView

Исходный код

Требование: предполагается, что вы ознакомились с вводными руководствами и запустили приложение Phoenix.

Требование: предполагается, что вы ознакомились с руководством по жизненному циклу запроса.

Мы уже рассмотрели, как работает типичный жизненный цикл запроса в Phoenix: запрос сопоставляется с маршрутом, контроллер обрабатывает запрос и обращается к представлению, чтобы вернуть ответ в нужном формате. Но что, если мы хотим создавать интерактивные страницы? В типичном приложении с рендерингом на сервере для изменения содержимого страницы требуется либо отправить форму и отобразить новую страницу, либо перенести логику приложения на клиент (например, с помощью JavaScript-фреймворков jQuery, React, Vue и т. д.) и создать API, с которым будет взаимодействовать клиент.

Phoenix LiveView предлагает другой подход: всё состояние хранится на сервере, а пользователям предоставляются насыщенные возможности взаимодействия в реальном времени на основе HTML, сформированного на сервере. Это альтернатива JavaScript-фреймворкам на стороне клиента, позволяющая создавать динамичные интерактивные приложения, используя на клиенте минимум кода JavaScript.

Что такое LiveView?

LiveView — это процессы, которые получают события, обновляют своё состояние и отображают изменения на странице в виде различий.

Модель программирования LiveView — декларативная: вместо того чтобы говорить «когда произойдёт событие X, измени Y на странице», события в LiveView представляют собой обычные сообщения, которые могут приводить к изменениям состояния. После изменения состояния LiveView повторно отрисовывает соответствующие части HTML-шаблона и отправляет их в браузер, который обновляет страницу наиболее эффективным способом.

Состояние LiveView — это не что иное, как функциональные неизменяемые структуры данных Elixir. События представляют собой либо внутренние сообщения приложения (обычно отправляемые через Phoenix.PubSub), либо сообщения, отправленные клиентом/браузером.

Каждый LiveView сначала статически отрисовывается в рамках обычного HTTP-запроса, что позволяет быстро достичь «первой значимой отрисовки» (First Meaningful Paint), а также помогает поисковым системам и системам индексирования. Затем между клиентом и сервером устанавливается постоянное соединение для обмена событиями и изменениями страницы. Благодаря этому приложения LiveView быстрее реагируют на события пользователя: по сравнению с запросами без сохранения состояния, которым при каждом обращении нужно выполнять аутентификацию, декодирование, загрузку и кодирование данных, здесь требуется меньше работы и передаётся меньше данных. LiveView можно представить как «различия, передаваемые по сети».

LiveView и Controller + View

Контроллеры Phoenix и LiveView выполняют схожие задачи по обработке взаимодействия с пользователем, но работают совершенно по-разному:

Controller + View

  • Контроллеры обрабатывают каждую пару HTTP-запрос/ответ как отдельную транзакцию
  • Для каждой загрузки страницы или отправки формы требуется полный цикл запроса и ответа
  • Контроллеры не хранят состояние, а данные хранятся во внешних системах (базе данных, сеансе)
  • Представления — это отдельные модули, которые отображают шаблоны с данными, полученными от контроллеров
  • Для обновления страницы и динамического взаимодействия требуется либо полностью перезагружать страницу, либо писать собственный код JavaScript на стороне клиента

Подход LiveView

  • При первоначальной загрузке страницы используется обычный жизненный цикл запроса, после чего устанавливается двунаправленное соединение с помощью Phoenix Channels
  • Процесс LiveView сохраняет состояние на протяжении всего взаимодействия с пользователем
  • Изменения состояния автоматически запускают повторную отрисовку только изменившихся частей страницы
  • События передаются через постоянное соединение, а не отдельные HTTP-запросы
  • Для интерактивных функций требуется минимум JavaScript

LiveView объединяет задачи контроллеров и представлений в более целостную модель.

Простой пример

LiveView входит в состав новых приложений Phoenix по умолчанию. Рассмотрим простой пример:

defmodule MyAppWeb.ThermostatLive do
  use MyAppWeb, :live_view

  def render(assigns) do
    ~H"""
    Current temperature: {@temperature}°F
    <button phx-click="inc_temperature">+</button>
    """
  end

  def mount(_params, _session, socket) do
    temperature = 70 # Let's assume a fixed temperature for now
    {:ok, assign(socket, :temperature, temperature)}
  end

  def handle_event("inc_temperature", _params, socket) do
    {:noreply, update(socket, :temperature, &(&1 + 1))}
  end
end

В этом примере LiveView показаны основные этапы жизненного цикла:

  1. Функция обратного вызова mount/3 инициализирует состояние при запуске LiveView
  2. Функция render/1 определяет, что будет отображено, используя шаблоны HEEx
  3. Функция обратного вызова handle_event/3 обрабатывает события от клиента

Чтобы подключить это в маршрутизаторе:

defmodule MyAppWeb.Router do
  use MyAppWeb, :router

  pipeline :browser do
    ...
  end

  scope "/", MyAppWeb do
    pipe_through :browser
    ...

    live "/thermostat", ThermostatLive
  end
end

После отрисовки LiveView отправляется обычный ответ HTML. В файле app.js вы должны увидеть следующее:

import {Socket} from "phoenix"
import {LiveSocket} from "phoenix_live_view"

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})
liveSocket.connect()

Теперь клиент JavaScript подключится по WebSocket, а mount/3 будет вызвана внутри запущенного процесса LiveView.

Основные понятия

Сокет и состояние

Сокет LiveView — это основная структура данных, в которой хранится всё состояние LiveView. Это неизменяемая структура, содержащая «назначенные значения» (assigns) — данные, доступные в шаблонах. Если у контроллеров есть conn, то у LiveView есть socket.

Изменения сокета (с помощью assign/3 или update/3) запускают повторную отрисовку. Всё состояние хранится на сервере, а клиенту отправляются только различия, что сокращает сетевой трафик.

Жизненный цикл LiveView

У LiveView есть несколько важных этапов жизненного цикла:

  • mount — инициализирует LiveView параметрами, данными сеанса и сокетом
  • handle_params — обрабатывает изменения URL и соответствующим образом обновляет состояние LiveView
  • handle_event — обрабатывает взаимодействия пользователя, поступающие от клиента
  • handle_info — обрабатывает обычные сообщения процесса

Привязки DOM

LiveView предоставляет привязки DOM для удобного взаимодействия клиента с сервером:

<button phx-click="inc_temperature">+</button>
<form phx-submit="save">...</form>
<input phx-blur="validate">

Эти привязки автоматически отправляют события на сервер при возникновении указанных событий браузера. Затем они обрабатываются в handle_event/3.

Начало работы

Phoenix включает генераторы кода для LiveView. Попробуйте:

$ mix phx.gen.live Blog Post posts title:string body:text

Эта команда создаёт полноценную реализацию CRUD на LiveView, аналогичную mix phx.gen.html.

Подробнее о LiveView см. в документации Phoenix LiveView.

← Предыдущая страница JSON и API
Следующая страница → Управление ресурсами

Пакет Hex Предпросмотр Hex (текущий файл) Скачать версию ePub

Создано с помощью ExDoc (v0.40.3) для языка программирования Elixir

© 2014 Chris McCord
Licensed under the MIT License.
https://phoenix.hexdocs.pm/live_view.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API