感谢阅读这篇文章。过去几天我一直坚持使用RoR的问题。我在index.html.erb下面有一个表单:
<head>
<title>Ajax List Demo</title>
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tag %>
</head>
<body>
<h3>Add to list using Ajax</h3>
<% form_tag :action => :list , :method=>:get, :remote=>true do %>
Enter the public url:<%= text_field_tag 'url' ,'', :size => 80 %>
<%= submit_tag "Find" %>
<% end %>
<div id="my_list">
</div>
</body>
在控制器中我有:
def list
puts "here!!!!"
reader = Reader.new
@profiles = reader.processURL(params[:url]) #profileList =
respond_to do |format|
#format.html { render :partial=>true, :locals => { :profiles => @profiles}}#{ render :partial=>'profiles/list',:layout => false, :locals => { :profiles => @profiles}}
format.js {render :content_type => 'text/javascript', :locals => { :profiles => @profiles}}
# index.html.erb
# format.rss render :partial=>'profiles/list',:layout => false, :locals => { :profiles => @profiles}
end
远程UJS的js文件为list.js.erb
$("#my_list").html("<%= escape_javascript(render(:partial => "list"))%>");
问题是我无法在div标签my_list中获得结果来呈现部分_list.html.erb。我得到一个空白页面,406错误。如果我在控制器中取消注释渲染html代码,我会在浏览器中渲染部分后退。我有点卡住,我想提交表单和结果弹出my_list div。我是新手,所以如果我错过了一些明显的东西,请毫不犹豫地向我指出......我绝对愿意尝试。
将其更改为:
<html>
<head>
<title>Ajax List Demo</title>
<h1>Listing posts</h1>
<%= javascript_include_tag 'jquery.js' %>
<%= csrf_meta_tag %>
</head>
<body>
<h3>Add to list using Ajax</h3>
<% form_tag :action => :doit , :method=>:get, :remote=>true do %>
Enter the public url:<%= text_field_tag 'url' ,'', :size => 80 %>
<%= submit_tag "Find" %>
<% end %>
<div id="my_list">
</div>
控制器:
def doit
puts "here!!!!"
reader = Reader.new
@profiles = reader.processURL(params[:url])
respond_to do |format|
# format.html {render :partial=>true, :locals => { :profiles => @profiles}}#{ render :partial=>'profiles/list',:layout => false, :locals => { :profiles => @profiles}}
format.js #{render :content_type => 'text/javascript', :locals => { :profiles => @profiles}}
# index.html.erb
# format.rss render :partial=>'profiles/list',:layout => false, :locals => { :profiles => @profiles}
end
JS _doit.js.erb $(“#my_list”)。html(“&lt;%= escape_javascript(render(:partial =&gt;”doit“))%&gt;”);
最后是部分:
_doit.html.erb。
但是我仍然遇到406错误,我没有重复的_doit js或erb。有什么突出的不正确吗?再次感谢!
另一个更新:
我认为表单没有正确呈现:
渲染:
<% form_tag :action => :doit , :remote=>true, :id => 'myform' do %>
Enter the public url:<%= text_field_tag 'url' ,'', :size => 80 %>
<%= submit_tag "Find" %>
<% end %>
此:
<form accept-charset="UTF-8" action="/home/doit?id=myform&remote=true" method="post">
<div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="✓" />
<input name="authenticity_token" type="hidden" value="MLuau4hvfdGO6FrYCzE0c0JzwHhHKZqjmV49U673sK8=" />
</div> Enter the public url:
<input id="url" name="url" size="80" type="text" value="" />
<input name="commit" type="submit" value="Find" />
<input name="commit" type="submit" value="Find" />
好的,最后得到一个线索形式需要括号:
<%= form_tag( { :action => 'doit' }, :multipart => true, :remote=>true, :id => 'myform' ) do %>
今晚最后一次更新: 现在我进入日志:
于10月27日星期三22:40:55 -0400 2010年开始发布“/ home / doit”for 127.0.0.1 这里!!!! 由HomeController处理#doit作为JS 参数:{“commit”=&gt;“Find”,“url”=&gt;“http://www.facebook.com/people/James-Stewart/653161299”,“authenticity_token”=&gt;“MLuau4hvf dGO6FrYCzE0c0JzwHhHKZqjmV49U673sK8 =“,”utf8“=&gt;”Γ£ô“”} 渲染回家/ _doit.html.erb(4.0ms) 渲染home / doit.js.erb(9.0ms) 在807ms完成200 OK(浏览次数:40.0ms | ActiveRecord:0.0ms)
我看作JS,它说它呈现我的js / partial。但是我在my_list div上什么都没得到。我的JS文件:
$("#my_list").html("<%= escape_javascript(render(:partial => "doit"))%>");
我的html.erb表单文件现在已经:
<script$('#myform').bind('ajax:success', function(evt, data, status, xhr){
xhr.responseText;
});></script>
它就像表格什么都不做,这是一个好兆头,没有406错误。我知道这很接近,如果有人可以在js中指出我需要做什么,那将是很好的,否则我会休息一下并尝试tmrw。
好的,我认为它的回复只是没有像你指出的那样呈现,这将是昨天Steve的问题。
在Firebug上调试JS我看到了我想在div中呈现的html,为此:
http://localhost:3000/javascripts/prototype.js?1285674435/event/seq/1
这意味着我认为我现在正在收到JS回复。
我在表单页面上有这个:
<script>$('#myform').bind('ajax:success', function(evt, data, status, xhr){
$('#my_list').html(eval(xhr.responseText));
});</script>
检查说它不知道myform是什么,但我把:id =&gt; Rails代码中的'myform'。
再次感谢,我在这里得到了很多帮助,我想分享一下我最终如何回到社区。 p>
方法doit的js文件(def。需要一个更好的控制器动作名称)是doit.js
代码最终是:
$("my_list").update("<%= escape_javascript(render(:partial => "doit"))%>");
出于某种原因,在Firefox中找不到#my_list,我不得不使用firebug来最终解决这个问题。
显然这与下面建议的方式不同,我将把js脚本放回到表单中并删除.js.erb文件,看看它是如何工作的。我想我只是在format.js响应中渲染部分?还有谁在哪里找到有关写UJS文件的信息?我对以$开头的任何语法都一无所知。
再次感谢您的帮助,最后感觉我在学习轨道方面取得了进展。
答案 0 :(得分:26)
我在Hacker News上发布了这个答案,但认为Stack Overflow社区也可能受益: - )
在Rails 3中,javascript驱动程序非常不干涉(即不引人注目)。您遇到的问题是您的应用程序正在返回浏览器中的一串javascript,但页面中没有任何内容可以在页面上下文中执行该javascript。
rails.js ujs驱动程序绑定到data-remote=true
的表单和链接,这是:remote => true
正在做的事情,使他们远程提交请求,但这就是Rails魔法停止的地方。
好消息是远程请求会触发您可以绑定的某些事件,这些事件可以让您访问服务器返回的数据(按以下顺序触发):
ajax:before
ajax:loading
ajax:success
ajax:complete
ajax:failure
ajax:after
您需要将事件绑定到表单的ajax:success
事件。因此,如果您的表单的ID为“myform”,则您需要在页面上显示以下内容:
$('#myform').bind('ajax:success', function(evt, data, status, xhr){
eval(xhr.responseText);
});
xhr.responseText
是您的服务器返回的内容,因此只需将其作为javascript执行。
当然,也可以通过一些错误处理来绑定故障事件。
我通常甚至不使用action.js.erb方法返回javascript,我只是让我的控制器渲染HTML部分,然后我在页面中有这样的绑定:
$('#myform').bind('ajax:success', function(evt, data, status, xhr){
$('#target-div').html(xhr.responseText);
});
我实际上正在撰写关于此的完整文章,但希望这足以让你前进。
编辑:我完成了那篇文章,完整地解释了Rails 3中的远程链接和表单。也许它会有所帮助:
答案 1 :(得分:6)
如果查看页面的渲染源,您应该注意到fields属性中的错误。
正确的方法如下:
<%= form_tag({:action => 'list'}, :remote => true %>
注意大括号,非常重要!或者你可以做到:
<%= form_tag('list', :remote => true %>
答案 2 :(得分:2)
你有2个名为'_list'的部分?也许这会导致问题,你应该更具体一点:
$("#my_list").html("<%= escape_javascript(render(:partial => "list.html.erb"))%>");
我不确定这是否有帮助,但如果你在IE中使用,请注意IE会发送一些与控制器响应方式相关的标题。因此,您可能正在向IE发送Ajax请求,但您的Rails应用程序认为它只是一个简单的HTML请求。
我必须设置jQuery才能首先擦除当前标头,然后只添加javascript标头:
$.ajaxSetup({
'beforeSend': function(xhr) {xhr.setRequestHeader("Accept",'');xhr.setRequestHeader("Accept", "text/javascript")}
})
答案 3 :(得分:1)
在控制器中使用list
作为功能名称可能是个问题。该名称由Rails内部使用。
答案 4 :(得分:0)
Rails 5.1引入了rails-ujs,它更改了这些事件处理程序的参数。以下应该起作用:
$('#myform').bind('ajax:success', function(event) {
const [_data, _status, xhr] = event.detail;
});
来源:https://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html#rails-ujs-event-handlers
答案 5 :(得分:0)
我知道这是一个老问题,但是有人可以从中受益。
我认为错误与此有关:
JS _doit.js.erb $(“#my_list”)。html(“ <%= escape_javascript(render(:partial =>” doit“))%>”))
最后是部分:
_doit.html.erb。
您正在创建_doit.js.erb
部分以响应控制器中的动作doit
,但是您需要的是称为doit.js.erb
的视图(不带下划线) )。从概念上讲,您的操作中的format.js
将响应带有扩展名js.erb
的同名视图。