如何在Phoenix应用的多模板中全局访问变量
在Phoenix中实现全局数据加载(类似Express中间件)
针对你的需求,Phoenix里对应Express中间件的方案分两种场景:传统控制器渲染的页面,和LiveView页面,下面分别说明:
一、传统控制器页面(非LiveView)
Phoenix的Plug就是和Express中间件对应的机制,你可以写一个全局Plug来加载数据并注入到所有请求的assigns中:
- 新建一个Plug文件
lib/app_web/plugs/assign_global_data.ex:
defmodule AppWeb.Plugs.AssignGlobalData do import Plug.Conn def init(opts), do: opts def call(conn, _opts) do # 加载你需要的全局数据,比如新闻列表 news = App.News.all() # 把数据存入conn的assigns,后续模板就能直接用@news assign(conn, :news, news) end end
- 在路由的
browser管道中添加这个Plug,确保所有浏览器请求都经过它:
打开lib/app_web/router.ex,修改browser管道:
pipeline :browser do plug :accepts, ["html"] plug :fetch_session plug :fetch_live_flash plug :put_root_layout, html: {AppWeb.LayoutView, :root} plug :protect_from_forgery plug :put_secure_browser_headers # 新增这行,加入全局数据Plug plug AppWeb.Plugs.AssignGlobalData end
这样根模板(比如lib/app_web/templates/layout/app.html.heex)里就能直接使用@news变量了。
二、LiveView页面
如果你的应用基于LiveView,或者需要在LiveView中全局加载数据,有两种实现方式:
方式1:根LiveView的mount方法
如果所有页面都基于同一个根LiveView,直接在它的mount回调里添加assign:
defmodule AppWeb.AppLive do use AppWeb, :live_view alias App.News @impl true def mount(_params, _session, socket) do # 加载全局数据 news = News.all() # 把数据存入socket的assigns socket = assign(socket, :news, news) {:ok, socket} end end
根LiveView的assign会自动传递给所有子LiveView,对应的根模板(比如lib/app_web/templates/layout/live.html.heex)也能直接用@news。
方式2:全局on_mount钩子(更灵活)
如果需要给所有LiveView统一注入数据,或者只想给部分LiveView添加,用on_mount钩子更合适:
- 在
lib/app_web/live/live_helpers.ex中定义钩子:
defmodule AppWeb.LiveHelpers do import Phoenix.LiveView def on_mount(:assign_global_data, _params, _session, socket) do news = App.News.all() # :cont 表示继续执行LiveView的初始化流程 {:cont, assign(socket, :news, news)} end end
- 在
lib/app_web.ex的live_view宏中注册这个钩子,让所有LiveView自动加载:
def live_view do quote do use Phoenix.LiveView, layout: {AppWeb.LayoutView, :live} unquote(view_helpers()) # 新增这行,注册全局on_mount钩子 on_mount AppWeb.LiveHelpers, :assign_global_data end end
这样所有LiveView都会自动带上@news这个assign。
注意
如果你的应用同时存在传统控制器页面和LiveView页面,需要同时配置上述两种方案,确保根模板在两种场景下都能访问到@news。
内容的提问来源于stack exchange,提问作者flaudre
相关产品推荐
相关产品推荐

