如何在js文件中执行elixir代码? [英] How to execute elixir code in a js file?

查看:133
本文介绍了如何在js文件中执行elixir代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个jsmy_js_file.js文件,我只将其包含在一个页面中。在那个js文件中,我需要通过调用凤凰助手获取一个URL:

 #my_js_file.js 

function func1(userLogin){
var createUserUlr =<%= user_home_path(@ conn,:create,userLogin)%>;
// ...........

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

解决方案

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

请记住这是的事情!服务器不需要在每个页面请求上重新呈现您的Javascript。



您可以通过多种方式获得所需的结果:



硬编码



可能看起来很hacky,但对于简单的情况来说效果还不错。我建议硬编码只是一个路径,在开始时使用 // 来保留当前协议(http / https)。如果您需要将其解析为完整的URL,可以使用这个技巧



数据属性



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

 < div id =create-userdata-url =<%= user_home_path (@ conn,:create,userLogin)%>> 
<! - ... - >
< / div>

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

 让createUserUrl = document.querySelector(#create-user)。getAttribute(data-url); 

如果您只需要定位IE11 +或愿意使用 polyfill ,你也可以使用 dataset

 让createUserUrl = document.querySelector(#create-user)。dataset.url; 

或者如果你正在使用jQuery:

 让createUserUrl = $(#create-user)。data(url); 

也许您可以从其他属性中提取URL,例如<$ c $如果您要覆盖提交的 onclick 处理程序,则c> url 表单按钮,例如。



窗口添加属性对象



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

 < script> window .userToken =<%=分配[:user_token]%>;< / script> 

然后在您的JavaScript中,您只需访问

  window.userToken 



其他解决方案



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




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


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




我'我确定现在还有更多我没想到的选择。


I have a js "my_js_file.js" file which I include only into a single page. In that js file I need to get an url by calling a phoenix helper:

# my_js_file.js

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

But it doesn't work. When I rename it to "my_js_file.js.eex", it still doesn't work -- the value between "<%= %>" isn't getting evaluated. Why not? And what are the options? Note that I'm passing a variable to the url.

解决方案

I don't think this is possible, because the assets in the static/ directory are not processed by Elixir, but by your asset pipeline (Brunch by default). They are pre-compiled so even if it worked, you would not have access to the @conn variable, since this is not available at the time when static assets are compiled.

Keep in mind this is a good thing! The server does not need to re-render your Javascript on every page request.

You have several options to get the desired result:

Hard coding

Might seem hacky, but works well enough for simple cases. I recommend hard coding just a path, using // at the start to preserve the current protocol (http/https). If you need to resolve this to a full URL, you can use this trick.

Data attributes

For one-off usage, you can add a data attribute to a related portion of your markup, for example for a login form:

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

Then in your JavaScript, you can access the data attribute. Note that depending on your use case, there might be a better way to retrieve the DOM node containing the data attribute than using document.querySelector, this is just an example:

let createUserUrl = document.querySelector("#create-user").getAttribute("data-url");

If you only need to target IE11+ or willing to use a polyfill, you can also use dataset

let createUserUrl = document.querySelector("#create-user").dataset.url;

Or if you're using jQuery:

let createUserUrl = $("#create-user").data("url");

Maybe you'll be able to extract the URL from a different attribute such as the url of a form, should you be overriding the onclick handler of the submit button, for example.

Add property on window object

For truly global values, such as authentication tokens etc. you can set a property on the window object, for example in web/templates/layout/app.html.eex

<script>window.userToken = "<%= assigns[:user_token] %>";</script>

then in your JavaScript, you can simply access

window.userToken

Other solutions

There are also more advanced solutions available for this problem, including:

  • Add a separate JSON endpoint that returns the required data as JSON which can then be requested from your JavaScript

  • If you use a JavaScript framework such as React.js, Vue.js, etc. you might be able to leverage routing logic from the framework or auxiliary JavaScript packages.

I'm sure there's even more options I didn't think of right now.

这篇关于如何在js文件中执行elixir代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆