【问题标题】:How to make a variable globally accessible across multiple templates如何使变量在多个模板中全局可访问
【发布时间】:2022-08-17 09:27:11
【问题描述】:

在我的 phoenix 应用程序中,我正在尝试加载一堆数据并使它们可以访问我的根模板(跨所有页面)。据我所知,这是通过分配完成的,但我不知道在哪里加载它。

我想像

use App.LiveView
use App.News

assign(socket, news: News.all)

应该可以工作,但我不知道把这段代码放在哪里,所以套接字是可用的。来自 Express.js,我正在寻找类似的东西:

router.use((req, res, next) => {
  // Load news into global variable
  // ...
  next()
})

感谢您的帮助。

  • 您是否尝试过使用插件将您需要的数据注入到 assings 中?

标签: elixir phoenix phoenix-live-view


【解决方案1】:

Express'router.use 的非 LiveView Phoenix 等效项将是 Router.plug/2。您可以在pipeline 中添加一个插件。

一个插件既可以定义为一个模块,也可以定义为一个简单的函数。

这是一个最小的例子:

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    # ...
    plug :my_plug  # <= add your plug
  end

  def my_plug(conn, _opts) do
    Plug.Conn.assign(conn, :news, News.all())
  end

但这不适用于 LiveView,它无法访问插头分配。从 LiveView 0.17 开始,您可以使用 mount hook 来实现此目的。您需要将on_mount/1 添加到您的AppWeb.live_view/0

def live_view do
  quote do
    use Phoenix.LiveView,
      layout: {AppWeb.LayoutView, "live.html"}

    on_mount AppWeb.NewsLiveFetcher  # <= add this
    unquote(view_helpers())
  end
end

并实现AppWeb.NewsLiveFetcher 类似:

defmodule AppWeb.NewsLiveFetcher do
  import Phoenix.LiveView

  def on_mount(:default, _params, _session, socket) do
    socket = assign_new(socket, :news, &News.all/0)
    {:cont, socket}
  end
end

【讨论】:

    猜你喜欢
    • 2017-02-24
    • 2014-07-20
    • 1970-01-01
    • 1970-01-01
    • 2020-05-12
    • 1970-01-01
    • 2016-09-28
    • 2021-08-07
    • 2019-12-05
    相关资源
    最近更新 更多