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 %>
""" 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"""
""" 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