2016-12-05 56 views
2

我沿着RoR入門指南進行操作,並隨着我的進行添加了一些內容。具體來說,我想實現的是在步驟5.13 Deleting Articles中,我使用AJAX刪除了一篇文章,而不是使用標準模式。Ruby on Rails防止Turbolinks劫持AJAX操作

我想這樣做的方式最適合RoR的做事方式。閱讀Working with JavaScript in Rails章節後,下面的步驟似乎是要走的路:

  1. 加入data: {turbolinks: false}添加屬性remote: truelink_to助手(見代碼片段A)
  2. 禁用turbolinks這link_to幫手(見代碼片段A)
  3. 向控制器添加一些邏輯,以確保返回JSON(請參閱代碼段B)。
  4. 添加監聽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 

回答

1

我會來這個個人以不同的方式。

查看: 觸發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 

這將處理銷燬方法和返回的javascript,默認情況下,這將與destroy.js返回。 erb文件在相關的目錄中

destroy.js.erb:

$("#article").slideToggle(300, function(){ 

    $("#article").remove(); 

}); 

FYI:http://api.jquery.com/slidetoggle/

希望這有助於有點

+0

感謝Brad,文件'destroy.js.erb'在哪裏存在?在'\ views \ articles'文件夾中? – Hendrik

+0

是的,這是正確的 – Brad

+0

對不起,我只是注意到我錯過了':remote => true'位的鏈接,我編輯答案 – Brad

0

嘗試修改您的片段A和使用no_turbolink:真

代碼片段A

<td data-no-turbolink="true"><%= link_to 'Destroy', 
     article_path(article), 
     method: :delete, 
     data: {no_turbolink: true, remote: true}, 
     :class=> 'remove-article' %></td> 

生成的鏈接的html應該有它下面的代碼:

data-no-turbolink="true" 

編輯:添加數據沒有的TurboLink =「真」的標籤,希望這有助於在那裏,根你的問題是禁用turbolink,只要我們實現它,我認爲你應該是好的。

Opting out of Turbolink

+0

我想這一點,並將得到的HTML現在看起來是這樣的: ''Destroy可惜 這並沒有改變任何東西 – Hendrik

+0

@Hendrik編輯,添加data-no-turbolink =「true」給td標籤,試試吧請試試 – IKA

+0

好吧,現在還加了'​​''但還是沒有運氣 'Destroy ' – Hendrik