将数据从Phoenix传递到Javascript的最佳实践

时间:2016-08-20 08:35:26

标签: elixir phoenix-framework

我看到了3种方法。

  1. <%= %>
  2. 中的<script>内使用*.html.eex
  3. 使用渠道将数据传递给Javascript
  4. 构建json api
  5. #1似乎是最简单的,但我找不到或想到一个很好的方法来做到这一点。

    注意:实时更新不是我的要求。

4 个答案:

答案 0 :(得分:3)

(2)如果你不想要实时更新,那不是一个好主意。 (3)如果您不想使用AJAX加载数据,可能会过于复杂。你应该使用(1)如果你只是需要一些数据可以从JS访问而不想在没有整页重新加载的情况下进行更改。

由于有效的JSON也是有效的JS,因此您可以使用Poison.encode!()。如果您的数据位于@posts,则可以在*.html.eex中执行此操作:

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

然后在此之后加载其他JS并使用全局POSTS变量访问帖子。 (您可能希望将其命名为App.posts = ...

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

确保@posts仅包含可转换为JSON(无元组)的数据,并且只包含允许用户查看的字段。

答案 1 :(得分:3)

我永远不会使用<script></script>,在我的项目中我有这种模式:

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

我总是在主布局中提供当前环境,我有一个config.js文件,其中包含适当环境的正确数据。

当我需要将一些数据传递给我的javascript时,我会在我的视图中执行类似的操作:

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

如果你用一些帮助(elixir方面)抽象,你可以这样做:

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

在javascript方面,当我加载页面时,我只提取data-属性并将它们设置为当前控制器的变量options

class ZombieController extends Controller

  setup: ->

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

    # I can do 
    zombies = @options.zombies

嗯,这只是一个例子,您应该根据当前项目进行调整。关键是抽象。

希望有所帮助:)

答案 2 :(得分:1)

最佳实践取决于您的前端。

如果您基本上使用javascript运行提供HTML。将数据注入html或通过脚本标记

如果要构建反应/角度/前端,请考虑使用API​​和/或通道。

一般来说,如果它是一个重要的网络应用程序,需要通过javascript操纵数据,我会去API /频道路线。

答案 3 :(得分:1)

你也可以使用hex PhoenixGon它使用第一种方式将Phoenix变量传递给Javascript。它接受来自controller和Mix.env的所有变量,并使用呈现的<script>生成JSON标记以及访问此数据的方法。见其他回答here。它就像:

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

在js Code:

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

你不需要创建@vars并保持清晰。

对于zommbies.coffee

class ZombieController extends Controller

  setup: ->

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