Eventos
phx-value
Read time: 4 minutes
Este guia é uma continuação direta do guia anterior
git clone https://github.com/adopt-liveview/v2-myapp.git --branch events-done.
Nas aulas anteriores vimos apenas como disparar eventos. Também na aula de renderização condicional com cond vimos o seguinte código:
defmodule MyappWeb.PageLive do
use MyappWeb, :live_view
def mount(_params, _session, socket) do
socket = assign(socket, temperature_celsius: 30)
{:ok, socket}
end
def render(assigns) do
~H"""
<div>
Current temperature: {@temperature_celsius}C
</div>
<div>
<%= cond do %>
<% @temperature_celsius > 40 -> %>
<p>🔥 Impossible to live 🔥</p>
<% @temperature_celsius > 30 -> %>
<p>Its hot</p>
<% @temperature_celsius > 20 -> %>
<p>Kinda cool</p>
<% @temperature_celsius > 10 -> %>
<p>Chill</p>
<% @temperature_celsius > 0 -> %>
<p>Chill</p>
<% true -> %>
<p>❄️⛄️</p>
<% end %>
</div>
<input type="button" value="Increase" phx-click="increase" />
<input type="button" value="Decrease" phx-click="decrease" />
"""
end
def handle_event("increase", _params, socket) do
socket = assign(socket, temperature_celsius: socket.assigns.temperature_celsius + 10)
{:noreply, socket}
end
def handle_event("decrease", _params, socket) do
socket = assign(socket, temperature_celsius: socket.assigns.temperature_celsius - 10)
{:noreply, socket}
end
end
Nosso código sempre aumentava ou diminuía a temperatura em 10 graus. E se quiséssemos opções para aumentar/diminuir em quantidades diferentes? Precisaríamos criar um evento para cada caso? Vamos conhecer o binding phx-value. Atualize seu page_live.ex assim:
defmodule MyappWeb.PageLive do
use MyappWeb, :live_view
def mount(_params, _session, socket) do
socket = assign(socket, temperature_celsius: 30)
{:ok, socket}
end
def render(assigns) do
~H"""
<div>
Current temperature: {@temperature_celsius}C
</div>
<div>
<%= cond do %>
<% @temperature_celsius > 40 -> %>
<p>🔥 Impossible to live 🔥</p>
<% @temperature_celsius > 30 -> %>
<p>Its hot</p>
<% @temperature_celsius > 20 -> %>
<p>Kinda cool</p>
<% @temperature_celsius > 10 -> %>
<p>Chill</p>
<% @temperature_celsius > 0 -> %>
<p>Chill</p>
<% true -> %>
<p>❄️⛄️</p>
<% end %>
</div>
<input type="button" value="+5" phx-click="add" phx-value-amount={+5} />
<input type="button" value="+10" phx-click="add" phx-value-amount={+10} />
<input type="button" value="-5" phx-click="add" phx-value-amount={-5} />
<input type="button" value="-10" phx-click="add" phx-value-amount={-10} />
"""
end
def handle_event("add", %{"amount" => amount}, socket) do
amount = String.to_integer(amount)
socket = assign(socket, temperature_celsius: socket.assigns.temperature_celsius + amount)
{:noreply, socket}
end
end
Desta vez substituímos os eventos "increase" e "decrease" por um evento genérico chamado "add" que recebe um phx-value-amount com um número. Seu handle_event/3 recebe %{"amount" => "+10"} como segundo parâmetro dependendo do botão clicado. É importante notar que parâmetros vindos do HTML sempre chegam em formato string (pois atributos HTML são strings), então devemos converter o número antes de fazer a soma.
#Resumindo!
-
O binding
phx-value-*pode ajudar a generalizar um evento para que seja reutilizável. -
Os dados que você recebe no
handle_event/3equivalem ao nome do binding HEEx:phx-value-testgera%{"test" => valor}. -
Valores vindos de um binding
phx-value-*são sempre strings.
Feedback
Got any feedback about this page? Let us know!