如何在js文件中执行elixir代码?

アレッ*_*ックス 1 javascript elixir phoenix-framework

我有一个js"my_js_file.js"文件,我只包含在一个页面中.在那个js文件中,我需要通过调用一个凤凰助手来获取一个url:

# my_js_file.js

function func1(userLogin) {
  var createUserUlr = "<%= user_home_path(@conn, :create, userLogin) %>";
  //...........
Run Code Online (Sandbox Code Playgroud)

但它不起作用.当我将其重命名为"my_js_file.js.eex"时,它仍然无效 - "<%=%>"之间的值未得到评估.为什么不?有什么选择?请注意,我将一个变量传递给url.

Pat*_*ity 6

我不认为这是可能的,因为static/目录中的资产不是由Elixir处理,而是由您的资产管道处理(默认情况下为Brunch).它们是预编译的,因此即使它有效,您也无法访问@conn变量,因为在编译静态资产时这是不可用的.

请记住,这是一个东西!服务器不需要在每个页面请求上重新呈现您的Javascript.

您有多种方法可以获得所需的结果:

硬编码

可能看起来很hacky,但对于简单的案例来说效果很好.我建议只对路径进行硬编码,//在开始时使用以保留当前协议(http/https).如果您需要将其解析为完整的URL,则可以使用此技巧.

数据属性

对于一次性使用,您可以将数据属性添加到标记的相关部分,例如登录表单:

<div id="create-user" data-url="<%= user_home_path(@conn, :create, userLogin) %>">
  <!-- ... -->
</div>
Run Code Online (Sandbox Code Playgroud)

然后在JavaScript中,您可以访问data属性.请注意,根据您的使用情况,可能有更好的方法来检索包含数据属性的DOM节点而不是使用document.querySelector,这只是一个示例:

let createUserUrl = document.querySelector("#create-user").getAttribute("data-url");
Run Code Online (Sandbox Code Playgroud)

如果您只需要针对IE11 +或愿意使用polyfill,您也可以使用dataset

let createUserUrl = document.querySelector("#create-user").dataset.url;
Run Code Online (Sandbox Code Playgroud)

或者如果你正在使用jQuery:

let createUserUrl = $("#create-user").data("url");
Run Code Online (Sandbox Code Playgroud)

也许你就可以提取不同的属性中的网址,如urlform,你应该是压倒一切的onclick提交按钮的处理程序,例如.

window对象上添加属性

对于真正的全局值,例如身份验证令牌等,您可以在window对象上设置属性,例如在web/templates/layout/app.html.eex

<script>window.userToken = "<%= assigns[:user_token] %>";</script>
Run Code Online (Sandbox Code Playgroud)

然后在您的JavaScript中,您可以简单地访问

window.userToken
Run Code Online (Sandbox Code Playgroud)

其他方案

此问题还有更高级的解决方案,包括:

  • 添加一个单独的JSON端点,以JSON的形式返回所需的数据,然后可以从JavaScript中请求

  • 如果您使用诸如React.js,Vue.js等JavaScript框架,您可能能够利用框架或辅助JavaScript包中的路由逻辑.

我相信我现在还没有想到更多的选择.