檢視原始碼 即時導覽

LiveView 提供功能,讓你可以使用瀏覽器的 pushState API來進行頁面導覽。使用即時導覽,可以更新頁面,而不用重新載入整個頁面。

你可以用兩種方式觸發即時導覽

例如,不要在範本寫以下程式碼

<.link href={~p"/pages/#{@page + 1}"}>Next</.link>

你可以寫

<.link patch={~p"/pages/#{@page + 1}"}>Next</.link>

或在 LiveView 寫

{:noreply, push_patch(socket, to: ~p"/pages/#{@page + 1}")}

當你要導向到目前 LiveView 時,必須使用「patch」操作。它只更新 URL 和目前的參數,而不掛載新的 LiveView。當使用 patch 時,handle_params/3 回呼會被呼叫,並將最少的變更傳送給客戶端。請參閱下一部分以取得更多資訊。

當你要解除目前的 LiveView 並掛載新的 LiveView 時,必須使用「navigate」操作。你只能在同一個階段內的 LiveView 間進行「navigate」。在重新導向期間,會將一個 phx-loading 類別新增到 LiveView,它可以指示使用者正在載入新的頁面。

如果你試著將 patch 套用到另一個 LiveView 或導向其他階段的 live,就會觸發重新載入整個頁面。這表示即使你的應用程式結構變更而沒有反映在導覽中,你的應用程式仍會繼續運作。

以下是快速摘要

  • <.link href={...}>redirect/2 基於 HTTP,任何地方都能使用,而且會重新載入整個頁面

  • <.link navigate={...}>push_navigate/2 能在同一個階段內的 LiveView 間進行使用。它們在保留目前佈局的同時掛載新的 LiveView

  • <.link patch={...}>push_patch/2 會更新目前的 LiveView,只傳送最小的差異,同時也能維持捲軸位置

handle_params/3

handle_params/3 回呼會在 mount/3 之後和初始渲染之前被呼叫。它也會在每次 <.link patch={...}>push_patch/2 被使用時被呼叫。它會收到第一個引數為請求參數、第二個引數為 URL、第三個引數為 socket 的部分。

例如,想像你有一個 UserTable LiveView 用於顯示系統中的所有使用者,而你在路由中這樣定義它

live "/users", UserTable

現在要加入即時排序,你可以這樣做

<.link patch={path(~p"/users", sort_by: "name")}>Sort by name</.link>

當使用者點擊後,由於我們正在導航到目前的 LiveView,handle_params/3 會被呼叫。請記住你絕不應該相信收到的 params,因此你必須使用回呼驗證使用者的輸入並相應地變更狀態

def handle_params(params, _uri, socket) do
  socket =
    case params["sort_by"] do
      sort_by when sort_by in ~w(name company) -> assign(socket, sort_by: sort_by)
      _ -> socket
    end

  {:noreply, load_users(socket)}
end

請注意,我們傳回 {:noreply, socket},其中 :noreply 表示不會傳送任何其他資訊給客戶端。如同其他 handle_* 回呼,在 handle_params/3 中對狀態的變更會觸發新的伺服器渲染。

請注意,傳遞給 handle_params/3 的參數和傳遞給 mount/3 的參數相同。因此,你如何決定要使用哪個回呼來載入資料呢?一般而言,資料應該總是載入到 mount/3 中,因為 mount/3 在 LiveView 生命週期中只會被呼叫一次。僅有你預期會經由 <.link patch={...}>push_patch/2 而變更的 params 必須載入到 handle_params/3 中。

例如,想像你有一個部落格。單一貼文的 URL 為:"/blog/posts/:post_id"。在貼文頁面中,你有留言,而且它們已經分頁。你使用 <.link patch={...}> 在使用者每次分頁時更新顯示的留言,並將 URL 更新為 "/blog/posts/:post_id?page=X"。在此範例中,你會在 mount/3 中存取 "post_id",並在 handle_params/3 中存取留言頁面。

取代頁面位址

LiveView 還允許取代目前的瀏覽器 URL。當你希望特定事件變更 URL 但又不污染瀏覽器歷程記錄時,這項功能會很有用。你可以把 <.link replace> 選項傳遞給任何導航輔助工具來做到這一點。

同一個頁面中的多個 LiveViews

LiveView 透過在範本中呼叫 Phoenix.Component.live_render/3 讓您在同一個頁面中擁有多個 LiveViews。不過,只有在路由中直接定義的 LiveViews 才能使用這裡說明的「Live 導航」功能。這一點很關鍵,因為 LiveViews 與您的路由器密切合作,並保證您只能導航到已知的路由。