Javascript 如何在js视图中将javascript变量传递给erb代码?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4959770/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:57:38  来源:igfitidea点击:

How to pass a javascript variable into a erb code in a js view?

javascriptruby-on-railsviewerb

提问by fespinozacast

I have this Javascript view in my Rails 3 project:

我的 Rails 3 项目中有这个 Javascript 视图:

app/views/expenses/new_daily.js.erb

应用程序/视图/费用/new_daily.js.erb

var i = parseInt($('#daily').attr('data-num')) + 1;
//$('#daily').append('agrego fila ' + i + ' <br />');

$('#daily').append('<%= escape_javascript(render(partial: 'new_expense', locals: { i: i })) %>');

$('#daily').attr('data-num', i);

I want to pass my 'i' javascript variable to a ruby partial through locals, How I can accomplish this?

我想通过本地人将我的 'i' javascript 变量传递给 ruby​​ 部分,我怎么能做到这一点?

采纳答案by Umer Hassam

As far as i know there is no way to do it directly and the reason is fairly simple too, html is executed at the server side and javascript is a client side language which means its executed in your local browser, thats why if you even try to pass a variable between the two you'll have to make a request to the server, However this problem is tackled by calling an AJAX request, this AJAX request does the same thing as sending a new request to the server however it does that without refreshing or reloading the page to it gives the users the illusion that no request was made.

据我所知,没有办法直接做到这一点,原因也很简单,html 在服务器端执行,而 javascript 是一种客户端语言,这意味着它在您的本地浏览器中执行,这就是为什么如果您甚至尝试要在两者之间传递一个变量,您必须向服务器发出请求,但是这个问题是通过调用 AJAX 请求来解决的,这个 AJAX 请求与向服务器发送新请求的作用相同,但是它没有刷新或重新加载页面会给用户一种没有发出请求的错觉。

a guy asks a similar question Here

一个人在这里问了一个类似的问题

and you can learn more about AJAX Here on MDN:

你可以在 MDN 上了解更多关于 AJAX 的信息:

回答by Thaha kp

Yes you can pass the value by using jquery;

是的,您可以使用 jquery 传递值;

<%=f.text_field :email ,:id=>"email_field" %>

<script type="text/javascript">
   var my_email= "[email protected]"
   $(document).ready(function(){
        $("#email_field").val(my_email);
   });
</script>

回答by Marek Sapota

Simple answer is you can't. Partials are expanded at server side, and JavaScript variables are set later at client side. You could make i(as a variable name) a parameter of the partial and use it there.

简单的答案是你不能。部分在服务器端扩展,JavaScript 变量稍后在客户端设置。您可以将i(作为变量名)作为部分的参数并在那里使用它。

render :partial => 'xx', :locals => { :variable => 'i' }

And in partial

并且在部分

alert(<%= variable %>);

回答by Sam Figueroa

Check out the gon gem. https://github.com/gazay/gon

看看 gon 宝石。https://github.com/gazay/gon

It gives you a simple object you can pass variables to that will be available to your scripts via window.gon

它为您提供了一个简单的对象,您可以将变量传递给该对象,该对象可通过以下方式用于您的脚本 window.gon

Also referenced here http://railscasts.com/episodes/324-passing-data-to-javascript

此处也参考 http://railscasts.com/episodes/324-passing-data-to-javascript

回答by user3670743

The best other answers here are right that this can't be done by passing the javascript variable into an erb partial, since it is rendered on the server, not the client.

这里最好的其他答案是正确的,这不能通过将 javascript 变量传递到 erb 部分来完成,因为它是在服务器上呈现的,而不是在客户端上呈现。

But since anyone looking for this is probably interested in a work-around solution, which I don't see here, I will post this example that works well with Rails UJS and Turbolinks.

但是,由于任何寻找此问题的人都可能对变通解决方案感兴趣,而我在这里没有看到,因此我将发布此示例,该示例适用于 Rails UJS 和 Turbolinks。

First, you set up your controller to return a partial as HTML:

首先,您将控制器设置为以 HTML 形式返回部分内容:

format.html { render partial: "new_expense" }

Next, write a javascript AJAX function in app/views/expenses/new_daily.js.erb:

接下来,在 中编写一个 javascript AJAX 函数app/views/expenses/new_daily.js.erb

var i = parseInt($('#daily').attr('data-num')) + 1;

$.ajax({
  url: '/daily',
  type: 'GET',
  dataType: 'html',
  contentType: "application/html",
  success: function(response) { 

      $('#daily').replaceWith(response)

      $('#daily').attr('data-num', i);
  }
});

This is going to get your Rails partial as an html fragment that you can use to replace that part of your rendered page. You can use jQuery to get your data-numattribute value, do some math on it, replace the partial in your view, and then set the attribute value again.

这将使您的 Rails 部分作为 html 片段,您可以使用它来替换呈现页面的那部分。您可以使用 jQuery 获取data-num属性值,对其进行一些数学运算,替换视图中的部分,然后再次设置属性值。

You may ask why go to all the trouble of getting the Rails partial and replace it on the page, instead of just getting the data attribute, doing math on it, and setting that? The answer is that this is the best, and perhaps the only way of doing something which is really essential when rendering a Rails partial using UJS while handling an asynchronous response to an action.

您可能会问,为什么要费力地获取 Rails 部分并在页面上替换它,而不是仅仅获取数据属性,对其进行数学运算并进行设置?答案是,这是最好的,也许是唯一一种在处理对动作的异步响应的同时使用 UJS 渲染 Rails 部分时真正必要的方法。

If you are handling an asynchronous response from your server in a create.js.erbtemplate, then your variables (@daily, for example) are not going to reflect the work done after the request has completed (for example, if there has been processing on a background server like Sidekiq). In that case you don't have up-to-date action response variables to pass into your Rails partial in the js.erbfile, but you also can't pass the javascript dataresponse into your partial, as pointed out in this question.

如果您在create.js.erb模板中处理来自服务器的异步响应,那么您的变量(例如@daily)不会反映请求完成后所做的工作(例如,如果后台服务器上有处理)像 Sidekiq)。在这种情况下,您没有将最新的操作响应变量传递到js.erb文件中的Rails 部分,但您也无法将 javascriptdata响应传递到您的部分中,如本问题所述。

As far as I know, this approach is the only way to get a fully up-to-date partial after receiving a response to an asynchronous response (not shown). This get you the up-to-date partial, allows you to get your javascript into it, and is flexible enough to work in pretty much any use case.

据我所知,这种方法是在收到对异步响应(未显示)的响应后获得完全最新部分的唯一方法。这为您提供了最新的部分,允许您将 javascript 放入其中,并且足够灵活,几乎可以在任何用例中工作。

回答by Julia Usanova

1) You may create a js tag with global variable in you erb template, after that you will be able to access that variable from any js file

1)你可以在你的erb模板中创建一个带有全局变量的js标签,之后你就可以从任何js文件访问该变量

<%= javascript_tag do %>
   window.productsURL = '<%= j products_url %>';
<% end %>

2) You can pass data to data-attribute in erb template and access it by js on client side that way $('#products').data('products')

2)您可以将数据传递给erb模板中的数据属性,并在客户端通过js访问它 $('#products').data('products')

<%= content_tag "div", id: "products", data: {products: Product.limit(10)} do %>
   Loading products...
<% end %>

3) You can use gon, to use your Rails variables in your js

3)您可以使用gon,在您的 js 中使用您的 Rails 变量

There is a good article, read it and fine solution for your specific case http://railscasts.com/episodes/324-passing-data-to-javascript, more comments are here http://railscasts.com/episodes/324-passing-data-to-javascript?view=asciicast

有一篇很好的文章,阅读它并针对您的特定情况提供很好的解决方案 http://railscasts.com/episodes/324-passing-data-to-javascript,更多评论在这里http://railscasts.com/episodes/324 -passing-data-to-javascript?view=asciicast

回答by Greg

Here's a few different options on how to do it:

以下是有关如何执行此操作的几个不同选项:

http://jing.io/t/pass-javascript-variables-to-rails-controller.html

http://jing.io/t/pass-javascript-variables-to-rails-controller.html

回答by Art Shayderov

Let's make shure we understand each other. Your erb template (new_daily.js.erb) will be processed on the server side, ruby code will be evaluated (within <% %>), substitution made, and then resulting javascript will be sent to browser. On the client side the browser will then evaluate this javascript code and variable iwill be assigned a value.
Now when do you want to pass this variable and to what partial?

让我们确保彼此了解。您的 erb 模板 ( new_daily.js.erb) 将在服务器端处理,将评估 ruby​​ 代码(在 内<% %>),进行替换,然后将生成的 javascript 发送到浏览器。在客户端,浏览器将评估此 javascript 代码,并为变量i分配一个值。
现在你想什么时候传递这个变量以及什么部分?