问题
I am following along the RoR getting started guide and adding a few things as I go along. Specifically, what I would like to achieve is that in step 5.13 Deleting Articles, I delete an article using AJAX instead of using the standard pattern.
I want to do so in a way that fits in best with the RoR way of doing things. After reading the Working with JavaScript in Rails chapter, the following steps seemed like the way to go:
- Add property
remote: true
to thelink_to
helper (See code snippet A) - Disable turbolinks this
link_to
helper by addingdata: {turbolinks: false}
(See code snippet A) - Add a some logic to the controller that will make sure JSON is returned (see code snippet B).
- Add JavaScript that listens for the
ajax:success
events and then animates the item away (see code snippet C).
Snippet A
<td><%= link_to 'Destroy',
article_path(article),
method: :delete,
data: {turbolinks: false, remote: true},
:class=> 'remove-article' %></td>
Snippet 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
Snippet 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);
});
}
})();
This isn't quite working as I expected:
- The turbolinks disabling hasn't worked: it is still replacing the full page content.
- The event
ajax:success
event is triggered but when I inspect the data property of that event, I see some weird stuff. It seems a textual representation of what Turbolinks is about to do / has just done (?!).Turbolinks.clearCache() Turbolinks.visit("http://localhost:3000/articles", {"action":"replace"})
I am obviously doign this wrong. Can someone please explain to me how I should be doing this? I.e. not just how to get it to work, but also in an idiomatic RoR way?
EDIT
I found out which part was the culprit: it was Snippet B because the format.html was being run before the format.json. Simply switching these two fixed the issue:
Revised snippet 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>
Revised snippet 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
回答1:
I would come at this a different way personally.
View: trigger ajax call to delete article
<td><%= link_to 'Destroy default', article, method: :delete, :remote => true, :class=> 'remove-article' %></td>
Controller:
def destroy
@article.destroy
respond_to do |format|
format.js
end
end
this will process the destroy method and return javascript, by default this will return with the destroy.js.erb file in the relevant directory
destroy.js.erb:
$("#article").slideToggle(300, function(){
$("#article").remove();
});
FYI: http://api.jquery.com/slidetoggle/
Hope this helps somewhat
回答2:
Try modifying your Snippet A and using no_turbolink: true
Snippet A
<td data-no-turbolink="true"><%= link_to 'Destroy',
article_path(article),
method: :delete,
data: {no_turbolink: true, remote: true},
:class=> 'remove-article' %></td>
Resulting link html should have the following code in it:
data-no-turbolink="true"
EDIT: Added data-no-turbolink="true" to the tag, hopefully it helps there, the root of your problem is disabling turbolink, as soon as we achieve it I think you should be good.
Opting out of Turbolink
来源:https://stackoverflow.com/questions/40982356/ruby-on-rails-prevent-turbolinks-from-hijacking-ajax-action