【问题标题】:How to pass a javascript variable into a erb code in a js view?如何在 js 视图中将 javascript 变量传递给 erb 代码?
【发布时间】:2011-06-24 23:47:15
【问题描述】:

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

app/views/expenses/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);

我想通过 locals 将我的 'i' javascript 变量传递给 ruby​​ 部分,我该怎么做?

【问题讨论】:

    标签: javascript ruby-on-rails view erb


    【解决方案1】:

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

    一个人问了类似的问题Here

    您可以了解更多关于 AJAX 的信息Here on MDN

    【讨论】:

    • +1 表示答案,-1 表示指向 w3shcools。每个 web 开发者都应该知道 w3schools 非常糟糕,看看w3fools 找出原因。应该使用 Mozilla 开发者中心来获取文档。
    • 仅供参考,HTML 不在服务器端执行,ERB 是。 ERB 是用于生成 HTML 的模板语言。然后将 HTML 发送到客户端并在客户端呈现。
    【解决方案2】:

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

    <%=f.text_field :email ,:id=>"email_field" %>
    
    <script type="text/javascript">
       var my_email= "my@email.com"
       $(document).ready(function(){
            $("#email_field").val(my_email);
       });
    </script>
    

    【讨论】:

    • 啊哈。所以现在,假设表单生成器 f.正在建模 :user,点击提交按钮会将“my@email.com”发送到 params[:user][:email] 中的 Rails。完美,这就是我想要的。
    • 问题是如何将值从 javascript 传递到 Ruby ERB 部分呈现在 Rails 不显眼的 javascript 控制器操作响应(js.erb 文件)中。此答案描述了如何使用 javascript 设置表单字段的值。所以这不是问题的答案,尽管有最多的投票。
    • 伙计们,除了属性,你还能传递 object.id 吗?我在事件控制器的索引操作中使用带有引导模式的 fullcalendar,当窗口弹出时,我可以使用 fullcalendar 预先设置字段的表单 attr 值(所以我不需要预先使用 params [: id] 在控制器中)。我想将它作为 Rails 表单提交的原因是为了进行服务器端验证。你能告诉我如何将 id 传递给 form_for 帮助器来更新给定的对象,以及我的控制器索引操作与 @event 对象的样子吗?
    【解决方案3】:

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

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

    部分

    alert(<%= variable %>);
    

    【讨论】:

    • 为什么你说你不能传递一个变量然后提供一个与你的陈述相矛盾的例子,你本质上是传递i的内容以通过JS在客户端发出警报?
    【解决方案4】:

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

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

    这里也有引用 http://railscasts.com/episodes/324-passing-data-to-javascript

    【讨论】:

      【解决方案5】:

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

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

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

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

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

      有一篇很好的文章,阅读它并为您的具体案例提供很好的解决方案 http://railscasts.com/episodes/324-passing-data-to-javascript, 更多的cmets在这里http://railscasts.com/episodes/324-passing-data-to-javascript?view=asciicast

      【讨论】:

      • 感谢指向 javascript_tag 的指针。标记中的那个和 eval 以非常简单的方式完成了这个技巧。我猜 SO 用户不赞成,因为这更像是模板,而不是在运行时“通过”。但是,如果您可以在渲染页面时将数据写入 DOM,为什么还要使用 AJAX 枪:)
      【解决方案6】:

      【讨论】:

      • 欢迎来到 Stack Overflow,一般情况下,我们避免发布单个链接作为答案,想总结一下吗?
      【解决方案7】:

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

      但是,由于任何寻找这个的人都可能对我在这里看不到的变通解决方案感兴趣,所以我将发布这个适用于 Rails UJS 和 Turbolinks 的示例。

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

      format.html { render partial: "new_expense" }
      

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

      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);
        }
      });
      

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

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

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

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

      【讨论】:

        【解决方案8】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-21
          • 1970-01-01
          • 1970-01-01
          • 2020-07-11
          • 1970-01-01
          • 2018-01-09
          相关资源
          最近更新 更多