3

我是 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, '#') %>");
    }
});

});

我哪里错了?

4

1 回答 1

1

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

undefined method `link_to'

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

$(document).ready(function(){

您不需要在.js.erb模板中使用它,因为没有触发 ready 事件。如果 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 => true从表单选项中删除

  2. 添加:format => :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从服务器返回 pure:

    render :json => resource.to_json(:include => :errors)
    
于 2013-04-12T14:59:34.343 回答