由於 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}。
