由於 LiveView 可以不需要換掉整個頁面,所以我們可以把新增修改的表格放到 modal,這也成了現在 LiveView 表格常見的做法 (當然把複雜的大表格做成獨立的 LiveView 頁面也是可以的)。
在 Router 的 :index
路徑下方加入 :new
路徑:
live "/", NoteLive.Index, :index
live "/new", NoteLive.Index, :new
這麼一來,/new
就一樣會連到 NoteLive.Index
,我們可以透過 live_sction
是 :index
還是 :new
來判斷是不是要顯示 modal 表格。
在我們的 <.header>
component 增加一個新增按鈕,這個按鈕會連到 /new
路徑,這裡我們使用 <.link>
component 來產生連結:
之前在 Controller-View 時有使用 <.link href="目標路徑">
,這個接近原本 HTML 的 a, 會直接到新的畫面把目前的捨棄,但是在 LiveView 裡面,我們希望可以在不換頁的情況下,把目前的畫面換成新的畫面。.link
Component 提供了我們兩種選擇:
<.link navigate="目標路徑">
: 在兩個 LiveView 之間切換的時候使用,會在維持目前的 LiveView websocket 連線與 process 的情況換到下一個 LiveView 頁面。<.link patch="目標路徑">
: 在同一個 LiveView 的不同 query 或是 live_action 之間切換的時候使用,會重新呼叫 LiveView 的 handle_params
callback,並更新畫面。我們這一次要使用的是 patch,在 <.header>
的 actions 裡面加入:
<.header>
感激筆記 LiveView 版
<:actions>
<.link patch={~p"/new"}>
<.button>新增筆記</.button>
</.link>
</:actions>
</.header>
使用 core_component 預設的 <.modal>
component,並在 render
裡面加入判斷,如果 @live_action
是 :new
或是 :edit
(之後使用),就顯示 modal:
表格我們下一篇再加入,這裡先放一段文字代替:
def render(assigns) do
~H"""
<.table id="notes" rows={@notes}>
<:col :let={note} label="ID"><%= note.id %></:col>
<:col :let={note} label="內容"><%= note.content %></:col>
</.table>
<.modal :if={@live_action in [:new, :edit]} id="book-modal" show on_cancel={JS.patch(~p"/")}>
新增筆記表格
</.modal>
"""
end
在按下新增筆記按鈕時,卻發生錯誤了,原來 patch 會呼叫 handle_params
。
加入 handle_params callback
def handle_params(_params, _uri, socket) do
{:noreply, socket}
end
目前我們還沒有要在這邊處理任何事情,所以直接回傳 {:noreply, socket}
。