2014-01-09 62 views
13

我正在編寫一個Rails 4.0.2應用程序,並試圖在發生AJAX事件後在我的視圖中顯示Flash通知。ajax調用後,Rails不顯示Flash消息

在我看來,我顯示一個用戶可以點擊幾天的日曆。當他們這樣做時,我通過一個更新我的模型的onclick事件處理程序來觸發一個AJAX事件,這個事件處理程序可以添加或刪除記錄。在事件發生後,我完成頁面刷新以顯示更新的結果。

我發現我不得不在JS單擊事件期間進行頁面刷新,以便正確更新視圖。僅在控制器中進行重定向或渲染是不夠的。

所以,爲了這個效果,我已在我的控制器閃存通知...

def set_conflicts 
    @conflict = @member.conflicts.for_date(params[:date]).first 

    if @conflict 
    @conflict.destroy 
    else 
    conflict_date = Date.parse(params[:date]) 
    unless Conflict.create(
     month: conflict_date.month, 
     day: conflict_date.day, 
     year: conflict_date.year, 
     member: @member 
    ) 
     flash[:alert] = 'Oops, there was a problem updating conflicts' 
    end 
    end 
    flash[:notice] = 'This is a test!' 
    redirect_to manage_member_conflicts_path(@member) 
end 

...在我application.haml已包括以下Flash顯示的邏輯...

... 
%body 
    = p flash.inspect 
    - flash.each do |type, message| 
    = content_tag(:div, message, :class => "flash-#{type}") 

    = render 'devise/menu/login_items' 
    = yield 

注:我使用HAML代替ERB在我的意見

然而,沒有質W我嘗試的帽子,Flash消息不顯示。其他一切按預期工作,除了的快速消息,我一直沒能弄清楚爲什麼

我懷疑它與我正在做的與重定向(甚至可能turbolinks)結合的AJAX刷新有關,但我已經通過其他的答案看過,因此無法讓它工作。顯然,我錯過了一些東西。

這裏是JS點擊處理程序(它很簡單):

window.calendarClick = (eventDate, linkURL) -> 
    event = $(document.getElementById(eventDate)) 
    event.toggleClass('selected') 

    # Set or Remove conflicts 
    $.ajax 
    url: linkURL 
    data: 
     date: eventDate 

    # Refresh the page 
    $.ajax 
    url: '', 
    context: document.body, 
    success: (s,x) -> 
     $(this).html(s) 

回答

9

首先,感謝全面的問題

這裏同樣是一個全面的答案:How do you handle Rail's flash with Ajax requests?


阿賈克斯

我認真看看你的Ajax刷新過程。刷新整個頁面是超級低效的,而且我認爲覆蓋更深層次的問題

你爲什麼不嘗試使用.js.erb文件中的文件夾views,直接由該方法處理JS:

def set_conflicts 
    @conflict = @member.conflicts.for_date(params[:date]).first 

    if @conflict 
    @conflict.destroy 
    else 
    conflict_date = Date.parse(params[:date]) 
    unless Conflict.create(
     month: conflict_date.month, 
     day: conflict_date.day, 
     year: conflict_date.year, 
     member: @member 
    ) 
     flash[:alert] = 'Oops, there was a problem updating conflicts' 
    end 
    end 
    flash[:notice] = 'This is a test!' 

    respond_to do |format| 
     format.html { redirect_to manage_member_conflicts_path(@member) } 
     format.js 
    end 
end 

#app/views/controller/set_conflicts.js.erb 
$("#your_element").html(<%=j render manage_member_conflicts_path(@member)) %>); 

響應

雖然我不知道這肯定做,我知道Flash對象由ActionDispatch::Flash中間件處理。我相信這不會像標準HTTP請求一樣處理XHR,從而阻止Flash在您的響應中顯示。

這意味着您必須通過Ajax請求傳遞Flash對象。而據我張貼在這個答案的頂部的問題,你可以使用response headers做到這一點:

class ApplicationController < ActionController::Base 
after_filter :flash_to_headers 

def flash_to_headers 
    return unless request.xhr? 
    response.headers['X-Message'] = flash[:error] unless flash[:error].blank? 
    # repeat for other flash types... 

    flash.discard # don't want the flash to appear when you reload page 
end 

$(document).ajaxError(function(event, request) { 
    var msg = request.getResponseHeader('X-Message'); 
    if (msg) alert(msg); 
}); 
+0

很好的答案,謝謝Rich。我的主要問題是找到一種有效的方法來添加/刪除記錄基於用戶點擊的日期。我會按照你的建議調查重構。我已經嘗試了幾種設置請求標頭的方法,但是我確信這只是我對JS再次展示的缺乏經驗。 – Donovan

+0

想聊天嗎?這是你應該能夠做得相對簡單的事情 –

+0

如果/當你有時間時,我會。我創建了聊天室... http://chat.stackoverflow.com/rooms/44968/chat-with-donovan – Donovan

22

我想權衡的需要將消息傳遞給頭部似乎是一個圓 - 做一些事情的方式Rails應該已經能夠做到了。

幾個小時搜索,我意識到我已經做什麼需要通過將以下行中我的控制器來完成後:

flash[:error] = "My flash message error." 

respond_to do |format| 
    format.js 
end 

閃光燈[:錯誤]設置了以下查看Flash消息的的respond_to意識到我有遙控器:在我的link_to(原Ajax請求)真集:

<%= link_to "My Ajax Request", some_path(@some_value), remote: true %> 

並響應鏈接,如JavaScript。如果您仍然希望能夠在遠程設置爲true的情況下調用相同的控制器,則可以在此塊中包含format.html。

在我application.html.erb我有一個部分呈現的提示信息:

<%= render "layouts/flash_notices" %> 

和部分包含一個div,看起來像下面這樣:

<div id="flash_messages"> 
    <% flash.each do |type, message| %> 
    <p><%= type %>: <%= message %></p> 
    <% end %> 
</div> 

最後,我創建了一個查看名爲MY_CONTROLLER_ACTION_NAME.js.erb並插入:

<% flash.each do |type, message| %> 
    $("#flash_messages").html("<%= type.to_s.humanize %>: <%= message.html_safe %>") 
<% end %> 

現在當我點擊啓用了AJAX的鏈接,控制器動作被執行,flash消息被設置,控制器加載js.erb視圖,最後,執行javascript代替id =「flash_messages」的div內容。我原來的觀點是更新與閃光消息,一切都是正確的與世界。注意:如果您使用的是Bootstrap或其他特殊的CSS框架,您可以在js.erb文件的$(「#flash_messages')。html(」「); call中包含該代碼,包括我的Bootstrap代碼如下:

$("#flash_messages').html("<div class='alert <%= bootstrap_class_for(type) %> alert-dismissible' role='alert'><button class='close' data-dismiss='alert'>×</button><%= message.html_safe %></div>") 

我知道這個問題是幾個月前發佈,但對於這個具體問題上的反應似乎總是你需要通過頭髮送的提示信息搜索時,我想表現那裏。是另一種方法,希望這將有助於我的未來Rails新手!

+1

我喜歡它,這基本上是我最終做的。謝謝Celsian! – Donovan

+0

這是我的榮幸! – Celsian

+1

繁榮!謝謝你,先生! –

相關問題