【发布时间】:2015-08-14 03:30:20
【问题描述】:
我正在使用 Bootstrap 3 模式和 AJAX 向我的 Rails 应用程序添加一个新的 Sale_Contact。它不起作用 - 我从服务器返回 200 OK 代码,并且正在将对象添加到数据库中,但是因为没有返回 JSON(创建操作只是发回 create.js.erb 文件到 JQuery.parse.json 操作)然后我触发 ajaxError 而不是 ajaxSuccess,我的模式没有关闭,并且使用新的 sale_contact 对象更新视图的 javascript 没有执行。
我不明白为什么我的 Rails 控制器期望在这个实例中返回一个 Json 对象——我基本上是直接从我也用模态和 AJAX 构建的其他对象复制了这段代码,它们都运行良好。谁能帮我理解在这种情况下出了什么问题?
我的控制器:
def create
@sale_contact = SaleContact.new(sale_contact_params)
@sales_opportunity = @sale_contact.sales_opportunity
respond_to do |format|
if @sale_contact.save
#format.html { redirect_to @sale_contact.sales_opportunity, notice: 'Sale contact was successfully created.' }
format.js
#format.json { render json :show, status: :created, location: @sale_contact }
else
format.html { render :new }
format.json { render json: @sale_contact.errors, status: :unprocessable_entity }
format.js { render json: @sale_contact.errors, status: :unprocessable_entity }
end
end
end
我已经对此进行了测试,我可以看到 if @sale_contact.save 块正在运行。正如您在上面看到的,我还注释掉了 format.html 和 format.json 行,但这不会改变结果。
我的 Sale_Contacts 的 create.js.erb 文件:
console.log('anything at all');
//update the selection list with the new sale contact, and close the modal
$('#sales_opp_sale_contact_modal').modal('hide')
.clear_previous_errors();
resetForm($('#new_sale_contact'));
$input = $('#contact_error');
$input.closest('.form-group').removeClass('has-error').find('.warning-block').html('');
//render the newly added sale contact to the table if the AJAX call succeeded
console.log('fired');
$(document).ajaxSuccess(function() {
$( ".log" ).text( "Triggered ajaxSuccess handler. The ajax response was: " +
xhr.responseText );
$('#sales-opp-key-contacts-table-div').html("<%= escape_javascript(render :partial => 'sale_contacts/table')%>");
//console.log(document);
$('.alert').remove();
$('.navbar-default .navbar-nav > li > a').removeClass('selected');
$('#sale-contacts').DataTable({
retrieve: true,
});
此代码永远不会触发 - 而是将其传递回 ajaxError 函数:
Uncaught SyntaxError: Unexpected token c
jQuery.parseJSON @ jquery.js?body=1:8483
(anonymous function) @ organizations.js?body=1:23
jQuery.event.dispatch @ jquery.js?body=1:4642
jQuery.event.add.elemData.handle @ jquery.js?body=1:4310
jQuery.event.trigger @ jquery.js?body=1:4551
done @ jquery.js?body=1:9286
jQuery.ajaxTransport.send.callback @ jquery.js?body=1:9686
如你所见,我的 create.js.erb 文件开始的“c”字符被传入,它不是有效的 JSON,因此会抛出 parseError。
我添加了一些新代码来查看从 ajaxError 中返回的项目 - 以防这些帮助:
$(document).ready(function(){
$(document).on('ajaxError', function(XMLHttpRequest, textStatus, errorThrown){
console.log("some error" + errorThrown);
});
$(document).on('ajaxError', function(req, xhr, err){
console.log('my message' + err + xhr.status);
});
$(document).bind('ajaxError', function(event, jqxhr, settings, exception){
// note: jqxhr.responseJSON undefined, parsing responseText instead
console.log(jqxhr.responseText)
$(event.data).render_form_errors( $.parseJSON(jqxhr.responseText) );
});
由此产生的输出是:
some error[object Object]
my message[object Object]200
console.log('anything at all');
//update the selection list with the new sale contact, and close the modal
$('#sales_opp_sale_contact_modal').modal('hide')
.clear_previous_errors();
resetForm($('#new_sale_contact')); .....
为了简洁起见,我已对此进行了编辑,您可以看到前两个响应显示我正在发回对象(我如何找出哪个?)和 200 OK 代码,responseText 是 create.js。 erb 文件不会被触发。
我要疯了,想弄清楚为什么这不起作用。此对象与我以这种方式创建的其他对象之间的唯一区别是我的 Sale_Contact 是一个连接表(它属于 Sales_Opportunities 和 Key_Contacts,因此它们具有_many_through 这个表)。
如果重要的话,这里是模型:
class SaleContact < ActiveRecord::Base
validates :key_contact_id, presence: true
validates :sales_opportunity_id, presence: true
belongs_to :key_contact
belongs_to :sales_opportunity
enum role: [ :not_known, :evaluator, :decision_maker, :budget_holder ]
enum preference: [ :unknown, :supporter, :enemy ]
end
这是我的 sale_contacts/show.json.jbuilder 文件:
json.extract! @sale_contact, :id, :key_contact_id, :sales_opportunity_id, :role, :preference, :created_at, :updated_at
任何帮助将不胜感激
快速编辑 这是我的相关项目的 routes.rb 文件,我希望这可能是问题:
resources :sales_opportunities do
resources :timeline_events, shallow: true
resources :swots, shallow: true
resources :sale_contacts, shallow: true
end
第二次修改
就像写这篇文章的一个想法一样,我在我的其他模式中对 ajaxSuccess 事件进行了相同的 ajax 分析 - 它们也返回与上面完全相同的信息:
some error[object Object]
my message[object Object]200
whatever create.js.erb template was added successfully
所以问题不是来自服务器的返回——还有其他问题。我正在使用 Bootstrap 3 模态,所以也许我需要深入研究他们的 ajax 代码才能找到问题。
编辑 3 - 添加模态内容
<%= form_for(@sale_contact, :html => {role: :form, 'data-model' => 'sale_contact'}, remote: true) do |f| %>
<% if @sale_contact.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@sale_contact.errors.count, "error") %> prohibited this sale_contact from being saved:</h2>
<ul>
<% @sale_contact.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group" id= "contact_error">
<%= f.label :key_contact_id, :class => "control-label" %>
<div id="contact_select">
<%= f.collection_select :key_contact_id, @sales_opportunity.company.key_contacts(:full_name), :id, :full_name %>
</div>
<span class="warning-block"></span>
<span class="help-block"></span>
</div>
<div class="form-group">
<%= f.label :role, :class => "control-label" %>
</br>
<%= f.select(:role, options_for_select(@roles.collect { |r| [r[0].humanize, r[0]] }, selected: @sale_contact.role), {}) %>
<span class="help-block"></span>
</div>
<div class="form-group">
<%= f.label :preference, :class => "control-label" %>
</br>
<%= f.select(:preference, options_for_select(@preferences.collect { |r| [r[0].humanize, r[0]] }, selected: @sale_contact.preference), {}) %>
<span class="help-block"></span>
</div>
<div class="form-group">
<%= f.hidden_field :sales_opportunity_id, :value => @sales_opportunity.id %>
</div>
<%= f.submit "Save", class: "btn btn-large btn-success" %>
<% end %>
为了清楚起见 - 我为网站上的所有模式使用完全相同的模式布局(目前大约有 8 个工作),我只是剪切/粘贴代码并更改名称。 Modal 工作 - 一个新对象被持久化在数据库中 - Jquery 是问题所在。
【问题讨论】:
-
js 来确认这个 url 是如何从视图中调用的。通过放置
remote: true,在链接中或来自JQuery ajax 请求或其他东西。 -
是的,我在模态中调用 remote: true - 我将更新问题的内容以包含它。
-
那个 format.js 的实际响应体是什么?
-
对不起@SergioTulentsev - 你需要知道什么?来自 sale_contact 控制器的 format.js 的响应正文?如果是这样,那么我在 sale_contacts/create.js.erb 中有一个文件,由 format.js 行调用。响应正文包含 create.js.erb 文件的完整输出以及其中包含新对象的渲染部分 - 但这仅记录在控制台中。
-
啊,什么是请求/响应标头,尤其是
Content-Type?我怀疑是application/json。
标签: javascript jquery ruby-on-rails ajax json