Best practice to pass data from Phoenix to Javascript

此生再无相见时 提交于 2020-01-03 17:32:09

问题


I see 3 ways of doing this.

  1. Using <%= %> inside <script> in *.html.eex
  2. Use channels to pass data to Javascript
  3. Build a json api

#1 seems the easiest but I couldn't find or think of a good way to do it yet.

Note: real-time update is not my requirement.


回答1:


I would never use a <script></script> for that, in my projects I have this pattern:

<!-- Layout -->
<div id="config"
  data-environment="..."
></div>

I always provide the current environment in the master layout, I have a config.jsfile with the right data for the right environment.

When I need to pass some data to my javascript I do something like that in my view:

<div id="app"
  data-users="..."
  data-zombies="..."
  ...
></div>

If you abstract that with some helpers (elixir side) you can do:

<%= App.Helpers.make_html(:app, [users: @users, zombies: @zombies]) %>

In the javascript side, when I load the page I just extract the data-attributes and set them in a variable options for the current controller:

class ZombieController extends Controller

  setup: ->

    console.log(@options) # I have all the data there.

    # I can do 
    zombies = @options.zombies

Well, it's just an example and you should adapt that for your current project. The key is to abstract.

Hope it helps :)




回答2:


(2) is not a good idea if you don't want real time updates. (3) may be too unnecessarily complicated if you don't want to load the data using AJAX. You should use (1) if you just need some data to be accessible from JS and don't want to change it without a whole page reload.

Since valid JSON is also valid JS, you can just use Poison.encode!(). If your data is in @posts, you can do this in *.html.eex:

<script>
  var POSTS = <%= Poison.encode!(@posts) %>;
</script>

and then load other JS after this and access the posts using the global POSTS variable. (You might want to namespace it into something like App.posts = ...:

<script>
  var App = window.App || {};
  App.posts = <%= Poison.encode!(@posts) %>;
</script>

Make sure @posts only contains data that can be converted to JSON (no tuples) and only has the fields that the user is allowed to see.




回答3:


Best Practice depends on your front end.

If you are basically serving HTML with dribbles of javascript. Inject data into the html or via script tag

If you are building a react / angular / front end, then consider using an API and/or Channels.

In general, if it's a significant web app that will require data to be manipulated via javascript, I'd go the API/Channel route.




回答4:


Also you can use hex PhoenixGon it uses the first way for passing Phoenix variables to Javascript. It takes all variables from controller and Mix.env and generate <script> tag with rendered JSON and methods for accessing to this data. See other answeres here. It's like:

def index(conn, _params) do      
  conn = put_gon(conn, [users: Repo.all(Users), zompies: Repo.all(Zombies)])
  render(conn, "index.html", current_user: get_session(conn, :current_user))
end

And in js Code:

window.Gon.getAsset('users') #=> [user list]
windoe.Gon.isDev() # => true

And you don't need create @vars and keep it clear.

And for zommbies.coffee:

class ZombieController extends Controller

  setup: ->

    zombies = window.Gon.getAsset('zombies')


来源:https://stackoverflow.com/questions/39052160/best-practice-to-pass-data-from-phoenix-to-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!