我认为这里有几个错误来源:
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集成表单处理并自己编写它:
:remote => true
从表单选项中删除
添加:format => :json
到您的create
路线
resources :posts, :only => [:create], :format => :json
resources :posts, :except => [:create]
在您的资产中添加 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
});
现在你已经准备好JSON
从服务器返回 pure:
render :json => resource.to_json(:include => :errors)