如何递归渲染 LiveView 流?

问题描述 投票:0回答:1

我需要在累积先前状态的同时渲染 LiveView 流。对于常规集合,我会使用递归:

def mount(_, _, socket) do
  {:ok, assign(socket, list: [1, 2, 3])}
end

def render(assigns) do
  ~H"""
  <.list list={@list} prev="first" />
  """
end

defp list(%{list: []} = assigns), do: ~H""

defp list(assigns) do
  ~H"""
  <div>
    <%= "cur: #{hd(@list)}, prev: #{@prev}" %>
    <.list list={tl(@list)} prev={hd(@list)} />
  </div>
  """
end

如果我用 LiveView 流替换

list
可以吗?

phoenix-live-view
1个回答
0
投票

你绝对可以用流来做到这一点,甚至还有像

stream/4
stream_insert/4
stream_delete/3
这样的函数专门用于这种用途(这里不需要递归):

def mount(socket) do
    {:ok, stream_configure(socket, :songs, dom_id: &("songs-#{&1.id}"))}
end

def render(assigns) do
~H"""
<table>
    <tbody id="songs" phx-update="stream">
        <tr :for={{dom_id, song} <- @streams.songs} id={dom_id}>
            <td><%= song.title %></td>
            <td><button phx-click={JS.push("delete", value: %{dom_id: dom_id})}>delete</button></td>
            <td><button phx-click={JS.push("update", value: %{song_id: song.id})}>update</button></td>
        </tr>
    </tbody>
</table>
"""
end

def handle_event("delete", %{"dom_id" => dom_id}, socket) do
    {:noreply, stream_delete_by_dom_id(socket, :songs, dom_id)}
end

def handle_event("update", %{"song_id" => song_id}, socket) do
    song = get_song!(song_id)

    socket
    |> stream_delete(:songs, song)
    |> stream_insert(:songs, song, at: -1)
end
© www.soinside.com 2019 - 2024. All rights reserved.