更新: 我发现问题是库依赖问题。我没有安装
jquery-rails
gem,因此我不需要在我的应用程序中使用 jquery-ujs
库。简而言之,当我只有可用的内置 jquery-ujs
功能时,我正在使用 rails-ujs
语法:((掌心)。感谢所有查看并提供和回答的人。
我觉得我正在做一些相当基本的事情,但由于某种原因我无法弄清楚我做错了什么。我可以使用
remote: true
帮助器的 form_for
选项,通过 AJAX 成功异步创建记录。但是,我尝试返回的简单 JSON 结构似乎在 AJAX 响应的 data
对象中不可用。当我运行 console.log(data)
时,我在浏览器 js 控制台中得到 undefined
。
这是我的代码的相当准确的表示:
视图中的表格:
= form_for :thing, remote: true, html: { id: 'thing' } do |f|
= f.text_field :name
= f.submit 'submit'
我的控制器代码:
def create
@thing = Thing.new(thing_params)
if @thing.save
render json: { message: 'Thank you' }
else
render json: { message: 'oh no' }
end
end
我的 javascript/jQuery:
$(document).ready(function(){
$('#thing').on('ajax:success', function(e, data, status, xhr) {
console.log(data)
}).on('ajax:error', function(e, xhr, status, error){
console.log(error)
});
})
我疯狂地用谷歌搜索,但我只是不知所措。但也许我忽略了一些非常简单的事情。我很感激任何建议。
Rails UJS 默认发送远程请求
application/javascript
内容类型。
如果您想请求 JSON,请将
data-type="json"
属性附加到元素:
= form_for @thing, remote: true, html: { id: 'thing' }, data: { type: "json" } do |f|
= f.text_field :name
= f.submit 'submit'
还有 Turbolinks 的问题。您的代码将事件处理程序直接附加到元素:
$('#thing').on('ajax:success', function(e, data, status, xhr) {
console.log(data)
};
虽然这在初始页面加载时有效,但当 Turbolinks 用 Ajax 替换页面内容时,它就不起作用。相反,您需要创建一个幂等事件处理程序:
$(document).on('ajax:success', '#thing', function(e, data, status, xhr) {
console.log(data);
}).on('ajax:error', '#thing', function(e, xhr, status, error){
console.log(error);
});
这会将一个事件处理程序附加到文档本身,该处理程序将在 DOM 冒泡时捕获该事件。 因此,您不需要将此代码包装在
$(document).ready(function(){ ... });
中。
您还应该返回有意义的 HTTP 响应代码 - 这将决定 Rails UJS 是否触发
ajax:success
或 ajax:error
。不是 JSON 消息,它是反模式。
def create
@thing = Thing.new(thing_params)
if @thing.save
# Tell the client where the newly created object can be found
head :created, location: @thing
# or return a json representation of the object
render json: @thing, status: :created
else
# just return a header
head :unprocessable_entity
# or return a JSON object with the errors
render json: { errors: @thing.errors }, status: :unprocessable_entity
end
end