简体   繁体   English

如何使用HAML将JavaScript变量注入Ruby代码?

[英]How do I Inject a JavaScript variable into Ruby code using HAML?

I am trying to inject the filename JavaScript variable into my Ruby code like this: 我试图将filename JavaScript变量注入到我的Ruby代码中,如下所示:

"#{ajax_download_report_url(" + filename+ ")}"

It's a basic route URL but I need to pass this variable in HAML because I get it from this Ajax request: 这是一个基本的路由URL,但是我需要在HAML中传递此变量,因为我是从以下Ajax请求中获取的:

:javascript
        var updaterId = setInterval(function() {
          $.ajax({
            url: #{admin_reports_url.to_json},
            dataType: "json",
            type:  "GET",
            data: {job_id: "#{job_id}"},
            success: function(response){
              var filename = response.file;
              switch(status) {
                case 'failed':
                  $('.loader').hide();
                  clearInterval(updaterId);
                  alert(message);
                  break;
                case 'completed':
                  $('.loader').hide();
                  clearInterval(updaterId);
                  location.href = "#{ajax_download_report_admin_reports_url(" + filename+ ")}";
                  break;
              }
            }
          })}, 1000);

Now I have an error: 现在我有一个错误:

ActionController::RoutingError - No route matches 
{:controller=>"admin/reports", :action=>"ajax_download_report", :file=>" + filename+ "}

which means that HAML can't properly evalute this code. 这意味着HAML无法正确评估此代码。

This: 这个:

ajax_download_report_admin_reports_url(" + filename+ ")

is going to call a method in Ruby with a parameter of: 将在Ruby中使用以下参数调用方法:

" + filename+ "

Which is why you see: 这就是为什么您看到:

:file=>" + filename+ "

JavaScript is client-side running inside the browser, and can't touch the Ruby code on the server, so the JavaScript variable filename is invisible to Ruby and unreachable unless you send the value of filename back to the server somehow. JavaScript是在浏览器内部运行的客户端,无法触摸服务器上的Ruby代码,因此JavaScript变量filename对于Ruby是不可见的,并且无法访问,除非您以某种方式将filename的值发送回服务器。


What I've done in the past, when I had a similar need, was to generate the URL and store it in a JavaScript variable definition, then use JavaScript string concatenation to insert the URL in the right place. 过去,当我有类似需求时,我要做的是生成URL并将其存储在JavaScript变量定义中,然后使用JavaScript字符串串联将URL插入正确的位置。 Notice what this does: 注意这是做什么的:

File.dirname("http://foo.bar/baz/bor.html")
=> "http://foo.bar/baz"

It removes the resource name and leaves only the base URL. 它删除资源名称,仅保留基本URL。 Using that: 使用:

:javascript
  var admin_reports_base_url = "#{ File.dirname(ajax_download_report_admin_reports_url('foo')) }/"
  var updaterId = setInterval(function() {
    $.ajax({
      url: #{admin_reports_url.to_json},
      dataType: "json",
      type:  "GET",
      data: {job_id: "#{job_id}"},
      success: function(response){
        var filename = response.file;
        switch(status) {
          case 'failed':
            $('.loader').hide();
            clearInterval(updaterId);
            alert(message);
            break;
          case 'completed':
            $('.loader').hide();
            clearInterval(updaterId);
            location.href = admin_reports_base_url + filename;
            break;
        }
      }
    })}, 1000);
def get_url(x)
   return "a url: #{x}"
end

filename = 'abcd'

puts "#{get_url(filename)}"

--output:--
a url: abcd

But you are trying to use a js variable called filename, which does not exist until after the page is sent to the browser and after an ajax call is made some time later, in some ruby code that is executing now. 但是,您正在尝试使用一个名为filename的js变量,该变量在将页面发送到浏览器之后以及一段时间后进行ajax调用之后才存在,而现在正在执行的某些ruby代码中才存在。 No can do. 没办法

One solution would be to not use ruby code. 一种解决方案是不使用ruby代码。

eg: 例如:

location.href = "admin/reports/ajax_download_report?file=" + filename;
"#{ajax_download_report_admin_reports_url('')}" + filename

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM