如何在js文件中执行elixir代码? [英] How to execute elixir code in a js file?
问题描述
我有一个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屋!