我正在编写Rails 4.0.2应用程序,并试图在AJAX事件发生后在我的视图中显示Flash通知。
在我看来,我会显示一个日历,其中包含用户可以点击的天数。当他们这样做时,我会通过onclick事件处理程序触发AJAX事件,该事件处理程序会更新我的模型(添加或删除记录)。触发事件后,我将完成页面刷新以显示更新的结果。
我发现我必须在JS click事件期间进行页面刷新,以使视图正确更新。仅在控制器中进行重定向或渲染是不够的。
因此,为此,我在控制器中设置了Flash通知…
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中 包含以下闪光灯显示逻辑…
... %body = p flash.inspect - flash.each do |type, message| = content_tag(:div, message, :class => "flash-#{type}") = render 'devise/menu/login_items' = yield
注意:我在视图中使用HAML而不是ERB
但是,无论我如何尝试,都不会显示Flash消息。 除了 Flash消息 之外 ,其他一切都可以正常进行,我还无法弄清楚 原因 。
我怀疑这与AJAX刷新(与重定向(甚至可能是Turbolinks)结合在一起)有关,但是我在SO上浏览了其他答案,因此无法正常工作。显然,我缺少了一些东西。
这是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)
Ajax
我会认真考虑您的Ajax刷新过程。刷新整个页面效率极低,我认为涵盖了更深层次的问题
为什么不尝试使用该.js.erb文件views夹中的文件来通过该方法直接处理JS:
.js.erb
views
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中间件处理的。我认为XHR不能像处理标准HTTP请求那样处理XHR,因此会阻止在响应中显示Flash
这意味着您必须做一些事情才能通过您的Ajax请求传递Flash对象。根据我在此答案顶部发布的问题,您可以使用response headers来执行此操作:
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); });