【问题标题】:Embed ruby inside javascript在 javascript 中嵌入 ruby
【发布时间】:2013-04-12 10:56:19
【问题描述】:

我是 RoR 世界的新手。

虽然我已经使用 rails 脚手架生成了一些代码。我还可以使用 :remote => true 通过 ajax 发布表单。

表格被张贴了,干净整洁! 但我希望使用 link_to 渲染从我的控制器返回的一些数据,以便它创建到路由/资源的链接。

我尝试创建一个 .js.erb 文件并将代码嵌入其中,但它给了我一个错误提示:

undefined method `link_to'

.js.erb 中的代码

$(document).ready(function(){


$("#new_post").bind('ajax:success', function(xhr, data, status){ 
    console.log(data)
    if(data.errors){
        console.log("Error!")
    }
    else{
        var user_name = data.user; // json is contained in data variable        
        $("#recent_posts").prepend("<%= j link_to(user_name, '#') %>");
    }
});

});

我哪里错了?

【问题讨论】:

  • 你能把你的.js.erb文件的代码包括进来吗?
  • 解决此问题后,您可能需要将 Ruby 代码放在引号中,以免破坏您的 .prepend()
  • .js.erb 文件的路径是什么?如果它不在 app/views/_controller_name_ 中,您可能不在可以访问视图帮助器方法(如 link_to)的范围内。要测试是否是这种情况,请尝试通过将 link_to 替换为 ActionController::Base.helpers.link_to 来显式调用范围
  • 我试过做: $("#recent_posts").prepend("") 但没有不行!

标签: jquery ruby-on-rails ruby ujs


【解决方案1】:

我认为这里有几个错误来源:

undefined method `link_to'

这是非常不寻常的,因为link_to 是标准视图助手。你确定link_to 之前的空格真的是一个空格,而不是某种其他不可见的字符(例如,当你在持有alt 的同时使用space 时,你有时会在OSX 上得到那些)。此外,您的 js erb 必须在您的控制器视图命名空间中,但由于它在您呈现操作时被执行,因此似乎是这种情况。

$(document).ready(function(){

您不需要在.js.erb 模板中使用它,因为没有触发就绪事件。如果 DOM 无论如何都准备好了,jQuery 会立即执行脚本,所以它不会(通常)受到伤害,只是没有必要。

$("#new_post").bind('ajax:success', function(xhr, data, status){

这是一个更大的问题。您现在附加处理程序的方式,每次提交表单并且服务器返回数据时都会附加它。因此,如果出现错误,并且表单被提交并第二次返回,您将要么拥有 console 消息,要么执行两次锚插入。所以最好为这种事件做好准备:

$("#new_post").not('.registered').addClass('registered').bind('ajax:success', function(xhr, data, status){

这将阻止多个事件处理程序。

然后是第三个问题:

var user_name = data.user; // json is contained in data variable        
$("#recent_posts").prepend("<%= j link_to(user_name, '#') %>");

在这里,您尝试在 erb 内联 ruby​​ 中使用您在 javascript 中分配的变量。这不起作用,因为在渲染模板时,ruby 变量 user_name 在服务器端进行评估。另一方面,当客户端从服务器接收到呈现的模板时,会在浏览器中评估 javascript 变量分配。那么,你能做什么呢?

link_to 并不是那么神奇。它只是呈现一个锚标记。所以,同样可以这样写:

var user_name = data.user; // json is contained in data variable        
$("#recent_posts").prepend(["<a href='#'>", user_name, "</a>"].join(''));

到目前为止,一切都很好。您遇到的最大问题是:服务器无法同时返回渲染的.js.erb 模板 json 数据。因此,您在 javascript 函数中获得的数据将只是呈现的 .js.erb 模板字符串。与JSON中的服务器通信确实是最好的事情,所以我们把rails集成表单处理忘掉,自己写吧:

  1. 从表单选项中删除:remote =&gt; true

  2. :format =&gt; :json 添加到您的create 路由

    resources :posts, :only => [:create], :format => :json
    resources :posts, :except => [:create]
    
  3. 在您的资产中添加 javascript 以远程处理您的表单

    // after DOM ready
    
    var form = $('#new_post');
    form.on('submit', function(e) {
    
      $.ajax({
        url: form.prop('action'),
        type: form.prop('method') || 'POST' //for create action,
        data: form.serializeArray(),
        dataType: form.data('type') || 'json',
        success: function(data, status, xhr) {
              var user_name = data.user; // json is contained in data variable        
              $("#recent_posts").prepend(["<a href='#'>", user_name, "</a>"].join(''));
        },
        error: function(xhr, status, error) {
          console.log('error')
        }
      });
    
      return false; //prevent normal submit
    
    });
    
  4. 现在您可以从服务器返回纯 JSON

    render :json => resource.to_json(:include => :errors)
    

【讨论】:

  • 非常感谢。我想要 link_to 选项,以便我可以将其引用到资源路径。无论如何,您的回答更有意义。干杯!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-19
  • 1970-01-01
  • 2011-02-14
相关资源
最近更新 更多