最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

elixir - How to properly communicate with liveview from javascript - Stack Overflow

programmeradmin4浏览0评论

I'm trying to update Liveview with Javascript after a Javascript event is fired. Liveview must show a <div> element with some values sent from Javascript.

My question is: how should I pass those values from Javascript to Liveview?

I might also need value sent by Liveview in Javascript. Again: how should I pass those values from Liveview to Javascript?

There is a Livesocket created in Javascript for liveview to work but I see no way to get or set assign values from there. The only way to pass values from/to Liveview seem to be via the DOM at some point. For example:

<div id="lv-data" phx-hook="JavascriptHook"></div>
let hooks = {};
hooks.JavascriptHook = {
  mounted(){

    this.el.addEventListener("jsEvent", (e) => 
      this.pushEvent("jsEventToPhx", e.data, (reply, ref) => 
        console.log("not sure what to do here")));

    this.handleEvent("phxEventToJS", (payload) => console.log("data received: " + payload));
  }
}

This feel weird to have to use the DOM with a dummy <div> at all for pure data exchange...

I'm trying to update Liveview with Javascript after a Javascript event is fired. Liveview must show a <div> element with some values sent from Javascript.

My question is: how should I pass those values from Javascript to Liveview?

I might also need value sent by Liveview in Javascript. Again: how should I pass those values from Liveview to Javascript?

There is a Livesocket created in Javascript for liveview to work but I see no way to get or set assign values from there. The only way to pass values from/to Liveview seem to be via the DOM at some point. For example:

<div id="lv-data" phx-hook="JavascriptHook"></div>
let hooks = {};
hooks.JavascriptHook = {
  mounted(){

    this.el.addEventListener("jsEvent", (e) => 
      this.pushEvent("jsEventToPhx", e.data, (reply, ref) => 
        console.log("not sure what to do here")));

    this.handleEvent("phxEventToJS", (payload) => console.log("data received: " + payload));
  }
}

This feel weird to have to use the DOM with a dummy <div> at all for pure data exchange...

Share Improve this question asked Jul 11, 2020 at 14:59 ogrogr 7007 silver badges27 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 6

Is your LiveView module implemented to handle the jsEventToPhx event you're sending from the front-end? You must have a parent LiveView or LiveViewComponent which implements the handle_event/3 callback for the this message. See:

https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#c:handle_event/3

For example (in your LiveView module):

def handle_event("jsEventToPhx", params, socket) do
  # Here the `params` variable is what you are sending form the
  # client-side, so it will be `%{foo: "bar"}` if you
  # follow the next example.
  {:reply, %{hello: "world"}, socket}
end 

Then in your Hook, all you need is to use this.pushEvent:

let hooks = {};
hooks.JavascriptHook = {
  mounted(){
    this.pushEvent("jsEventToPhx", {foo: "bar"}, (reply, ref) => 
     // this will print `{hello: "world"}` 
     console.log(reply)
    );
  }
}

This is the approach when you want to send data to LiveView and optionally receive the response immediately.

If you want to send something from LiveView to the client, then the process is slightly different. From LiveView you use push_event when returning a socket from any handle_event callback, for example:

{:noreply, push_event(socket, "phxEventToJS", %{abc: "xyz"})}

And in your Hook, you subscribe to events:

mounted(){
  this.pushEvent("jsEventToPhx", {foo: "bar"}, (reply, ref) => 
   // this will print `{hello: "world"}` 
   console.log(reply);
  }

  this.handleEvent("phxEventToJS", (payload) => {
    // this will print `{abc: "xyz"}`
    console.log(payload);
  }
}

It may be useful to check the client-server munication section here.

发布评论

评论列表(0)

  1. 暂无评论