iT邦幫忙

2023 iThome 鐵人賽

DAY 23
0
Modern Web

Phoenix 1.7 完全教學系列 第 23

23 LiveView Index 頁面

  • 分享至 

  • xImage
  •  

這個章節我們要把原本使用 Controller-View 的感激筆記頁面一步一步的改成 LiveView 版本,並加上一些新功能。

一樣先由 Router 開始

通常 LiveView 也是使用 RESTful 風格的路徑設定,所以通常在這邊的 note index 頁面會一樣用 /notes,但是在這篇教學一方面是想保留原本的 Controller-View 版本,另一方面是這個站的主要功能只有感激筆記,所以在這邊用 / 來取代 /notes,之後加上的新增頁面也會依照這個模式改為 /new

scope "/", GratitudeWeb do
  pipe_through :browser
  # 將原本的首頁用我們即將建立的 Index 取代
  live "/", NoteLive.Index, :index

  # 舊的 Controller-View 版本
  resources "/notes", NoteController, except: [:show]
  live "/demo", DemoLive
end

靜態的 Index 頁面

路徑設定好後在 lib/gratitude_web/live/note_live/index.ex 建立一個 NoteLive.Index LiveView module

defmodule GratitudeWeb.NoteLive.Index do
  use GratitudeWeb, :live_view

  alias Gratitude.Notes

  def mount(params, session, socket) do
    notes = Notes.list_notes()
    {:ok, assign(socket, notes: notes)}
  end

  def render(assigns) do
    ~H"""
    <.header>感激筆記 LiveView 版</.header>
    <.table id="notes" rows={@notes}>
      <:col :let={note} label="ID"><%= note.id %></:col>
      <:col :let={note} label="內容"><%= note.content %></:col>
    </.table>
    """
  end
end

https://ithelp.ithome.com.tw/upload/images/20231008/20141054njLfjThI9w.png

關於模組名稱

可以注意到跟上一個 LiveView 頁面 DemoLive 相比,我們使用
NoteLive.Index 來作為模組名稱,且檔案的位置也是 lib/gratitude_web/live/note_live/index.ex,雖然這次的範例只會有一個 LiveView 頁面,但是如果有多個頁面的話,可以把相關的頁面與共用 component 放在同一個資料夾下,如果有顯示單個 note 的頁面需求,就會有另一個 NoteLive.Show 的模組,並且放在 lib/gratitude_web/live/note_live/show.ex

Router 裡的 live 函式 與 live_action

DemoLive 的 live 函式沒有像這次的 NoteLive.Index 一樣後面多加一個參數 :index
我們先來看看 live 函式的定義

live(path, live_view, action \\ nil, opts \\ [])

DemoLive 的時候,我們忽略了第三個 action 讓它使用預設值 nil ,由於我們的 DemoLive 功能相當少所以不需要為他特別指定 action

如果有多個路徑要用同一個 LiveView 通常會用 action 來區分,
例如之後我們會需要新增 note 的路徑 (/new),又想要用同一個 LiveView 來處理的話,就會在 Router 裡面使用 action 來區分:

live "/", NoteLive.Index, :index
live "/new", NoteLive.Index, :new

這樣一來,在 LiveView Module 裡我們可以在 assigns map 使用 live_action 得到該值,例如:

def mount(params, session, socket) do
  case socket.assigns.live_action do
    :index -> # 如果是 index 頁面要做的事
    :new -> # 如果是 new 頁面要做的事
  end

  {:ok, socket}
end

或是在 heex template 上判斷依照不同的 action 來顯示不同的內容:

<.header>
  <%= if @live_action == :index do %>
    列出所有的感激筆記
  <% else %>
    新增感激筆記
  <% end %>
</.header>

上一篇
22 LiveView 生命週期
下一篇
24 CoreComponents
系列文
Phoenix 1.7 完全教學30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言