在javascript中嵌入ruby

时间:2013-04-12 10:56:20

标签: jquery ruby-on-rails ruby ujs

我是RoR世界的新手。

虽然我使用rails scaffold生成了一些代码。我也可以使用:remote =>通过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, '#') %>");
    }
});

});

我哪里错了?

1 个答案:

答案 0 :(得分:1)

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

undefined method `link_to'

这非常不寻常,因为link_to是标准视图助手。你确定link_to之前的空间确实是一个空格而不是某种其他不可见的字符(当你在space时使用alt时,你有时会在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内联红宝石中javascript中指定的变量。这不起作用,因为在呈现模板时,rubied变量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. 从表单选项

  2. 中删除:remote => true
  3. :format => :json添加到您的create路径

    resources :posts, :only => [:create], :format => :json
    resources :posts, :except => [:create]
    
  4. 在远程处理表单的资源中添加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
    
    });
    
  5. 现在您已准备好从服务器返回纯JSON

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