Rails 在 ajax 调用后不显示 Flash 消息 [英] Rails doesn't display flash messages after ajax call

查看:24
本文介绍了Rails 在 ajax 调用后不显示 Flash 消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个 rails 4.0.2 应用程序,并试图在 AJAX 事件之后让 Flash 通知显示在我的视图中.

I'm writing a rails 4.0.2 app, and am trying to get a Flash notice to display in my view after an AJAX event.

在我看来,我显示了一个日历,其中包含用户可以点击的天数.当他们这样做时,我通过 onclick 事件处理程序触发 AJAX 事件,该事件处理程序更新我的模型,添加或删除记录.触发事件后,我完成了页面刷新以显示更新的结果.

In my view I display a calendar with days a user can click on. When they do so, I fire an AJAX event via an onclick event handler which updates my model, either adding or removing a record. After firing the event, I complete a page refresh in order to display the updated results.

我发现我必须在 JS 单击事件期间刷新页面才能使视图正确更新.仅在控制器中进行重定向或呈现是不够的.

I found I had to do a page refresh during the JS click event in order to get the view to update properly. A redirect or render in the controller alone wasn't enough.

因此,为此,我在控制器中设置了 Flash 通知...

So, to that effect, I have set a Flash notice in my controller...

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...

... and have included the following flash display logic in my 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 消息都不会显示.其他一切都按预期运行除了闪现信息,我一直无法弄清楚为什么.

Yet, no matter what I try, the Flash message does not display. Everything else works as expected except the flash message, and I haven't been able to figure out why.

我怀疑这与我正在结合重定向(甚至可能是 turbolinks)进行的 AJAX 刷新有关,但我已经在 SO 上查看了其他答案,但根本无法使其正常工作.显然,我遗漏了一些东西.

I suspect it's got something to do with the AJAX refresh I'm doing combined with the redirect (and maybe even turbolinks) but I've looked through other answers here on SO and simply can't get it to work. Clearly, I'm missing something.

这是 JS 单击处理程序(非常简单):

Here's the JS click handler (it's pretty simple):

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)

推荐答案

首先,感谢您的全面提问

Firstly, thanks for comprehensive question

这是一个同样全面的答案:你如何处理Rail 的 Flash 与 Ajax 请求?

Here is an equally comprehensive answer: How do you handle Rail's flash with Ajax requests?

Ajax

我会认真查看您的 Ajax 刷新过程.刷新整个页面效率超级低,我认为覆盖了更深层次的问题

I'd seriously look at your Ajax refresh process. Refreshing the whole page is super inefficient, and I think covering a deeper issue

为什么不尝试使用views文件夹中的.js.erb文件,直接通过方法处理JS:

Why don't you try using a .js.erb file in the views folder, to handle JS directly by the method:

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 请求的处理方式不同,因此会阻止 Flash 显示在您的响应中

Although I don't know this for sure, I know the Flash objects are handled by ActionDispatch::Flash middleware. I believe this is not handled for XHR in the same way as standard HTTP requests, consequently preventing Flash from being shown in your response

这意味着您必须做一些事情才能通过您的 Ajax 请求传递 Flash 对象.根据我在此答案顶部发布的问题,您可以使用 response headers 来做到这一点:

This means you'll have to do something to pass the Flash object through your Ajax request. And according to the question I posted at the top of this answer, you can use the response headers to do it:

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);
});

这篇关于Rails 在 ajax 调用后不显示 Flash 消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆