我沿着RoR入門指南進行操作,並隨着我的進行添加了一些內容。具體來說,我想實現的是在步驟5.13 Deleting Articles中,我使用AJAX刪除了一篇文章,而不是使用標準模式。Ruby on Rails防止Turbolinks劫持AJAX操作
我想這樣做的方式最適合RoR的做事方式。閱讀Working with JavaScript in Rails章節後,下面的步驟似乎是要走的路:
- 加入
data: {turbolinks: false}
添加屬性remote: true
到link_to
助手(見代碼片段A) - 禁用turbolinks這
link_to
幫手(見代碼片段A) - 向控制器添加一些邏輯,以確保返回JSON(請參閱代碼段B)。
- 添加監聽
ajax:success
事件的JavaScript,然後將該項目動畫化(請參閱代碼段C)。
片段甲
<td><%= link_to 'Destroy',
article_path(article),
method: :delete,
data: {turbolinks: false, remote: true},
:class=> 'remove-article' %></td>
片段乙
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
片段Ç
(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"})
我明顯是這個錯誤。有人可以向我解釋我應該怎麼做?即不僅如何讓它工作,而且還以一種慣用的RoR方式?
編輯
我發現這部分是罪魁禍首:這是摘錄乙因爲format.html被正在format.json之前運行。簡單地切換這兩個固定的問題:
修訂片斷答:
<!-- 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
感謝Brad,文件'destroy.js.erb'在哪裏存在?在'\ views \ articles'文件夾中? – Hendrik
是的,這是正確的 – Brad
對不起,我只是注意到我錯過了':remote => true'位的鏈接,我編輯答案 – Brad