defmodule Test.ThermostatLive do
# In Phoenix v1.6+ apps, the line is typically: use MyAppWeb, :live_view
use Phoenix.LiveView
# use Phoenix.LiveComponent
def render(assigns) do
~H"""
<%= for {id, card} <- @cards do %>
<.live_component module={CardComponent} id={id} card={card} />
<% end %>
<hr />
<div>
<button name="foo" phx-click="click">Update all</button>
</div>
"""
end
def mount(_params, _session, socket) do
IO.inspect("mount")
cards = %{"first" => %{title: "foo"}, "second" => %{title: "bar"}}
{:ok, assign(socket, :cards, cards)}
end
def handle_event("click", _, socket) do
IO.puts("click root")
# update all the cards
cards =
socket.assigns.cards
|> Enum.map(fn {id, card} -> {id, %{card | title: card.title <> "."}} end)
|> Enum.into(%{})
{:noreply, assign(socket, :cards, cards)}
end
def handle_info({:updated_card, %{title: title}, id}, socket) do
IO.puts("updated_card")
old_cards = socket.assigns.cards
new_cards =Map.put(old_cards, id, %{title: title})
socket = assign(socket, :cards, new_cards)
{:noreply, socket}
end
end
defmodule CardComponent do
use Phoenix.LiveComponent
def render(assigns) do
~H"""
<div>
<button name="foo" phx-click="click" phx-target={@myself}><%= @card.title %></button>
</div>
"""
end
def handle_event("click", _, socket) do
IO.puts("click component")
# socket.assign()
old_card = socket.assigns.card
new_card = %{old_card | title: old_card.title <> "."}
IO.inspect socket.assigns
# notify the root LV that state has changed
send self(), {:updated_card, new_card, socket.assigns.id}
{:noreply, assign(socket, :card, new_card)}
end
end