iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Modern Web

速成 Phoenix, 2022年最受喜愛框架系列 第 22

{22, LiveView, "列表與Component"}

  • 分享至 

  • xImage
  •  

CRUD 的列表頁面

很遺憾,工作要做的畫面大部分都是表格,在我們開始做酷東西之前,我們先確認一下 LiveView 可不可以達成工作要求
我們可以使用一樣的 Post context

當然一切還是從 Router 開始

我們也可以用新的取代掉 resources("/posts", PostController),但這次我們先用個不同的路徑

lib/blog_web/router.ex 加上 live("/live_posts", PostLive.Index)

  scope "/", BlogWeb do
    pipe_through(:browser)
    resources("/notes", NoteController)
    resources("/posts", PostController)

    live("/counter", CounterLive)
    live("/live_posts", PostLive.Index) # 加在這邊

    get("/", PageController, :index)
  end

建立 PostLive.Index

一樣,路徑幫我們導到 PostLive.Index 模組,我們來建立一個
lib/blog_web/live/post_live/index.ex
通常 elixir 模組名稱會與他的路徑相對應,但方便整理就行了
BlogWeb.PostLive.Index

defmodule BlogWeb.PostLive.Index do
  # 引用 BlogWeb 裡的 live_view
  use BlogWeb, :live_view

  # alias 之前做的 Blog.Posts,稍後比較方便呼叫
  alias Blog.Posts

  # 在 mount 裡面 assign 所有的文章
  def mount(_params, _session, socket) do
    {:ok, assign(socket, :posts, Posts.list_posts())}
  end

  def render(assigns) do
    ~H"""
    <h1>LiveView 文章列表</h1>
    <%= for post <- @posts do %>
      <%= post.title %>
    <% end %>
    """
  end

https://ithelp.ithome.com.tw/upload/images/20220926/20141054EBJNCszCth.png
列表做好了

Component

好啦有點太簡單,我們在這邊開始用 component 來幫他延伸

component 就是一個收 assigns 變數,然後裡面有 sigil_H 的方法

使用的時候我們可以在另一個 sigil_H(~H""" """) 裡面使用 <> 來呼叫

  def render(assigns) do
    ~H"""
    <h1>LiveView 文章列表</h1>
    <table>
      <.table_head />
      <.table_body>
        <%= for post <- @posts do %>
          <.post_row post={post} />
        <% end %>
      </.table_body>
    </table>
    """
  end

  # 這是一個最簡單的 component 因為他就是單純的把一些 HTML 整理起來
  def table_head(assigns) do
    ~H"""
    <thead>
      <tr>
        <th>標題</th>
        <th>內容預覽</th>
        <th>動作</th>
      </tr>
    </thead>
    """
  end

  # 普通的 component 有 /> 結尾,如果想要包別的東西可以用
  # <.table_body>
  #   內容
  # </.table_body>
  # 
  # 我們可以用 `render_slot(@inner_block)` 來顯示內容
  def table_body(assigns) do
    ~H"""
    <tbody>
      <tr>
        <%= render_slot(@inner_block) %>
      </tr>
    </tbody>
    """
  end

  def post_row(assigns) do
    ~H"""
    <tr>
      <td><%= @post.title %></td>
      <td><%= String.slice(@post.body, 0..25) <> "..." %></td>
      <td>
        閱讀
        編輯
        刪除
      </td>
    </tr>
    """
  end
end

要注意的是 Component 在之前傳統 Controller View Template 裡的 template 裡面也可以使用
另外如果呼叫一個 Component 就跟普通方法一樣,如果是定義在不同的 Module,就需要寫出該 Module 名稱,如:

<AnotherModule.function_name />

https://ithelp.ithome.com.tw/upload/images/20220926/20141054VxvWQUA9Hp.png


上一篇
{21, LiveView, "簡單計數器"}
下一篇
{23, LiveView, "用LiveComponent新增"}
系列文
速成 Phoenix, 2022年最受喜愛框架30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言