我看到了3种方法。
<%= %>
<script>
内使用*.html.eex
#1似乎是最简单的,但我找不到或想到一个很好的方法来做到这一点。
注意:实时更新不是我的要求。
答案 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')