檢視原始碼 即時版面

從 Phoenix v1.7 開始,您的應用程式是由兩個版面組成的

  • 根部版面 - 這是 LiveView 和一般檢視都使用的版面,通常含有 head 與 body 標籤 alongside <html> 的定義。在根部版面中定義的任何內容都將保持不變,即使您在 LiveView 中現場導覽也是如此。根部版面通常會使用 put_root_layout 在路由器中宣告,並在佈局資料夾中定義成 "root.html.heex"

  • 應用程式版面 - 這是預設的應用程式版面,會呈現在一般的 HTTP 要求與 LiveView 上。預設為 "app.html.heex"

總體而言,這些版面可以在 components/layouts 中找出,並內嵌於 MyAppWeb.Layouts 中。

所有版面都必須呼叫 <%= @inner_content %> 才能注入由版面呈現的內容。

根部版面

"根部" 版面只會在最初的要求中呈現,因此它可以存取 @conn 指定。根部版面通常會在路由器中定義

plug :put_root_layout, html: {MyAppWeb.Layouts, :root}

根部版面也可以透過路由器中的 :root_layout 選項進行設定,透過 Phoenix.LiveView.Router.live_session/2

應用程式版面

"app.html.heex" 版面會與 @conn@socket 一起呈現。控制器和 LiveView 都明確定義了將使用的預設版面。詳見 MyAppWeb 中的 def controllerdef live_view 定義,以了解它如何包含其中。

對於 LiveView 而言,預設版面可以透過兩種不同的方式覆寫,以增加靈活性

  1. Phoenix.LiveView.Router.live_session/2 中的 :layout 選項被設定時,會覆寫透過 use Phoenix.LiveView 所提供的 :layout 選項

  2. 透過 {:ok, socket, layout: ...} 回傳的 :layout 選項的掛載,會覆寫任何先前設定的版面選項

LiveView 本身會在用 :container 標籤包裝的版面中呈現。

更新文件標題

由於 Plug 管道的根佈局是在 LiveView 外部進行處理,因此內容無法動態變更。例外情況之一是 HTML 文件標記 <title> 的情況。Phoenix LiveView 處理例外情況 @page_title 是分配的,允許動態更新頁面標題,這在使用即時導航時相當有用,或者在瀏覽器標籤中加上通知註解。例如,要在瀏覽器的標題列中更新使用者通知數量,請先在載入時設定 page_title 分配

def mount(_params, _session, socket) do
  socket = assign(socket, page_title: "Latest Posts")
  {:ok, socket}
end

然後在根佈局中存取 @page_title

<title><%= @page_title %></title>

也可以使用 Phoenix.Component.live_title/1 組件來支援在進行處理及後續的更新時,為頁面標題加上自動的前導和後綴

<Phoenix.Component.live_title prefix="MyApp  ">
  <%= assigns[:page_title] || "Welcome" %>
</Phoenix.Component.live_title>

儘管根佈局不會由 LiveView 更新,不過透過簡單地分配到 page_title,LiveView 會知道要更新標題

def handle_info({:new_messages, count}, socket) do
  {:noreply, assign(socket, page_title: "Latest Posts (#{count} new)")}
end

注意:如果您發現需要動態修補根佈局的其他部分,例如在即時導航時將新指令碼或樣式注入到 <head> 中,那麼應該是使用通常的、非即時的頁面導航。分配 @page_title 會直接更新 document.title,因此無法用來更新根佈局的任何其他部分。