Ruby Rails 阻止 Turbolinks 劫持 AJAX 行动
Ruby on Rails prevent Turbolinks from hijacking AJAX action
我正在按照 RoR 入门指南进行操作,并在进行过程中添加了一些内容。具体来说,我想实现的是,在步骤 5.13 Deleting Articles 中,我使用 AJAX 删除了一篇文章,而不是使用标准模式。
我想以最适合 RoR 做事方式的方式这样做。阅读 Working with JavaScript in Rails 章节后,以下步骤似乎是可行的方法:
- 将 属性
remote: true
添加到 link_to
助手(参见代码片段 A)
- 通过添加
data: {turbolinks: false}
禁用此 link_to
助手的涡轮链接(参见代码片段 A)
- 向控制器添加一些逻辑,以确保返回 JSON(参见代码片段 B)。
- 添加 JavaScript 以侦听
ajax:success
事件,然后将项目动画化(参见代码片段 C)。
代码段 A
<td><%= link_to 'Destroy',
article_path(article),
method: :delete,
data: {turbolinks: false, remote: true},
:class=> 'remove-article' %></td>
片段 B
def destroy
@article = Article.find(params[:id])
respond_to do |format|
if @article.destroy
format.html { redirect_to articles_path }
format.json { render json: @article }
else
format.html { render action: "index" }
format.json { render json: @article.errors, status: :unprocessable_entity }
end
end
end
代码段 C
(function(){
$(document).on('turbolinks:load', listenForArticleDelete);
function listenForArticleDelete() {
$('a.remove-article').on('ajax:success', function(e, data, status, xhr) {
// e.preventDefault();
console.log('DELETE: AJAX SUCCESS', e, '\n', data, '\n', status, '\n', xhr);
});
}
})();
这并不像我预期的那样有效:
- 禁用 turbolinks 无效:它仍在替换整个页面内容。
- 事件
ajax:success
事件被触发,但是当我检查该事件的数据 属性 时,我看到了一些奇怪的东西。它似乎是 Turbolinks 将要做什么/刚刚做了什么的文本表示(?!)。 Turbolinks.clearCache()
Turbolinks.visit("http://localhost:3000/articles", {"action":"replace"})
我显然做错了。有人可以向我解释我应该怎么做吗? IE。不仅如何让它工作,而且还以惯用的 RoR 方式?
编辑
我发现了哪个部分是罪魁祸首:它是 片段 B 因为 format.html 在 format.json 之前是 运行。只需切换这两个即可解决问题:
修改后的代码段 A:
<!-- Default delete -> format.html -->
<td><%= link_to 'Destroy default',
article_path(article),
method: :delete,
:class=> 'remove-article' %></td>
<!-- aSync delete -> format.json -->
<td><%= link_to 'Destroy aSync',
article_path(article),
method: :delete,
remote: true,
data: {turbolinks: false},
:class=> 'remove-article' %></td>
修改后的代码段 B:
def destroy
@article = Article.find(params[:id])
respond_to do |format|
if @article.destroy
# Must place json before html, otherwise html will be executed
format.json { render json: @article }
format.html { redirect_to articles_path }
else
format.json { render json: @article.errors, status: :unprocessable_entity }
format.html { render action: "index" }
end
end
end
尝试修改您的代码段 A 并使用 no_turbolink:true
代码段 A
<td data-no-turbolink="true"><%= link_to 'Destroy',
article_path(article),
method: :delete,
data: {no_turbolink: true, remote: true},
:class=> 'remove-article' %></td>
结果 link html 中应包含以下代码:
data-no-turbolink="true"
编辑:在标签中添加了 data-no-turbolink="true",希望对您有所帮助,您的问题的根源在于禁用 turbolink,尽快我们实现了我认为你应该很好。
我个人会以不同的方式来看待这个问题。
查看:
触发 ajax 调用以删除文章
<td><%= link_to 'Destroy default', article, method: :delete, :remote => true, :class=> 'remove-article' %></td>
控制器:
def destroy
@article.destroy
respond_to do |format|
format.js
end
end
这将处理 destroy 方法和 return javascript,默认情况下这将 return 与相关目录中的 destroy.js.erb 文件
destroy.js.erb:
$("#article").slideToggle(300, function(){
$("#article").remove();
});
仅供参考:http://api.jquery.com/slidetoggle/
希望这能有所帮助
我正在按照 RoR 入门指南进行操作,并在进行过程中添加了一些内容。具体来说,我想实现的是,在步骤 5.13 Deleting Articles 中,我使用 AJAX 删除了一篇文章,而不是使用标准模式。
我想以最适合 RoR 做事方式的方式这样做。阅读 Working with JavaScript in Rails 章节后,以下步骤似乎是可行的方法:
- 将 属性
remote: true
添加到link_to
助手(参见代码片段 A) - 通过添加
data: {turbolinks: false}
禁用此link_to
助手的涡轮链接(参见代码片段 A) - 向控制器添加一些逻辑,以确保返回 JSON(参见代码片段 B)。
- 添加 JavaScript 以侦听
ajax:success
事件,然后将项目动画化(参见代码片段 C)。
代码段 A
<td><%= link_to 'Destroy',
article_path(article),
method: :delete,
data: {turbolinks: false, remote: true},
:class=> 'remove-article' %></td>
片段 B
def destroy
@article = Article.find(params[:id])
respond_to do |format|
if @article.destroy
format.html { redirect_to articles_path }
format.json { render json: @article }
else
format.html { render action: "index" }
format.json { render json: @article.errors, status: :unprocessable_entity }
end
end
end
代码段 C
(function(){
$(document).on('turbolinks:load', listenForArticleDelete);
function listenForArticleDelete() {
$('a.remove-article').on('ajax:success', function(e, data, status, xhr) {
// e.preventDefault();
console.log('DELETE: AJAX SUCCESS', e, '\n', data, '\n', status, '\n', xhr);
});
}
})();
这并不像我预期的那样有效:
- 禁用 turbolinks 无效:它仍在替换整个页面内容。
- 事件
ajax:success
事件被触发,但是当我检查该事件的数据 属性 时,我看到了一些奇怪的东西。它似乎是 Turbolinks 将要做什么/刚刚做了什么的文本表示(?!)。Turbolinks.clearCache() Turbolinks.visit("http://localhost:3000/articles", {"action":"replace"})
我显然做错了。有人可以向我解释我应该怎么做吗? IE。不仅如何让它工作,而且还以惯用的 RoR 方式?
编辑
我发现了哪个部分是罪魁祸首:它是 片段 B 因为 format.html 在 format.json 之前是 运行。只需切换这两个即可解决问题:
修改后的代码段 A:
<!-- Default delete -> format.html -->
<td><%= link_to 'Destroy default',
article_path(article),
method: :delete,
:class=> 'remove-article' %></td>
<!-- aSync delete -> format.json -->
<td><%= link_to 'Destroy aSync',
article_path(article),
method: :delete,
remote: true,
data: {turbolinks: false},
:class=> 'remove-article' %></td>
修改后的代码段 B:
def destroy
@article = Article.find(params[:id])
respond_to do |format|
if @article.destroy
# Must place json before html, otherwise html will be executed
format.json { render json: @article }
format.html { redirect_to articles_path }
else
format.json { render json: @article.errors, status: :unprocessable_entity }
format.html { render action: "index" }
end
end
end
尝试修改您的代码段 A 并使用 no_turbolink:true
代码段 A
<td data-no-turbolink="true"><%= link_to 'Destroy',
article_path(article),
method: :delete,
data: {no_turbolink: true, remote: true},
:class=> 'remove-article' %></td>
结果 link html 中应包含以下代码:
data-no-turbolink="true"
编辑:在标签中添加了 data-no-turbolink="true",希望对您有所帮助,您的问题的根源在于禁用 turbolink,尽快我们实现了我认为你应该很好。
我个人会以不同的方式来看待这个问题。
查看: 触发 ajax 调用以删除文章
<td><%= link_to 'Destroy default', article, method: :delete, :remote => true, :class=> 'remove-article' %></td>
控制器:
def destroy
@article.destroy
respond_to do |format|
format.js
end
end
这将处理 destroy 方法和 return javascript,默认情况下这将 return 与相关目录中的 destroy.js.erb 文件
destroy.js.erb:
$("#article").slideToggle(300, function(){
$("#article").remove();
});
仅供参考:http://api.jquery.com/slidetoggle/
希望这能有所帮助