在挂载期间使用 LiveView 将值从客户端传递到 Phoenix 服务器

Passing a value from client to Phoenix server using LiveView during mount

我正在尝试将一个值从浏览器(例如,localstorage)传递到服务器,并在安装实时模板 (leex) 并创建 UI 视图时使其可用。仅尝试以下操作以获得如下所示的消息。

<JS>
let liveSocket = new LiveSocket("/live", Socket, {params: {init_state: "value from localstorage"}..

<Phoenix>
def mount(params, _session, socket) do
  IO.inspect(params)  # this returns "not route mounted"

get_connect_params/1 似乎是根据此问题页面 (https://github.com/phoenixframework/phoenix_live_view/issues/204) 执行此操作的方法。也是socket参数,不是params去寻找下的变量。

<JS>
let liveSocket = new LiveSocket("/live", Socket, {params: {init_state: "value from localstorage"}..

<Phoenix>
def mount(_params, _session, socket) do
  IO.inspect(get_connect_params(socket)["init_state"])  

def mount(params, _session, socket) do

在 LiveView 中,当您从路由器安装 LiveView 时,您尝试访问的第一个名为 params 的参数用于查询参数以及任何路由器路径参数,这不是您的情况,因为您正在调用它从模板。这就是您收到错误的原因。

获取您传递给 init_state 的值 let liveSocket = new LiveSocket("/live", Socket, {params: {init_state: "value from localstorage"}.. 您需要在

行中调用 get_connect_params/1 内容
def mount(_params, _session, socket) do
  init_state = get_connect_params(socket)["init_state"]

  IO.inspect(init_state)
end

需要注意的重要一点是 get_connected 只能在 mount 函数中使用。

另一种解决方案是使用hooks,它允许您在挂载(或其他事件)上调用任意 JS(例如从 localStorage 读取),然后向 LiveView 发送消息。

模板中的某处:

<div phx-hook="LoadIt"></div>

修改app.js:

let Hooks = {}
Hooks.LoadIt = {
  mounted() {
    this.pushEvent("foobar", {
      baz: localStorage.getItem("baz"),
    })
  },
}

let liveSocket = new LiveSocket("/live", Socket, {
  params: {_csrf_token: csrfToken},
  hooks: Hooks,
})

在您的 LiveView 中:

def handle_event("foobar", %{"baz" => baz}, socket) do
  # Do whatever with baz.
  {:noreply, socket}
end

此处有更多示例代码:https://thepugautomatic.com/2020/05/persistent-session-data-via-localstorage-in-phoenix-liveview/

对于这个特定的用例,显然比其他一些解决方案要多一些工作,但如果您还想根据 LiveView 中发生的事情更新 localStorage,这可能是一个不错的选择。