在ajax调用之后,Rails不显示flash消息

 小甜蜜陈诗蓉_614 发布于 2023-02-04 18:21

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

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

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

所以,为此,我在控制器中设置了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中包含以下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

然而,无论我尝试什么,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)

Celsian.. 22

我想权衡一下,因为需要将消息传递给头部,这似乎是做Rails应该已经能够做的事情的一种回合方式.

经过几个小时的搜索后,我意识到我已经通过在控制器中传递以下行来完成需要完成的工作:

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

respond_to do |format|
  format.js 
end

flash [:error]为以下视图设置Flash消息,respond_to意识到我在我的link_to(原始ajax请求)中设置了remote:true:

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

并作为JavaScript响应链接.如果您仍希望能够在没有远程设置为true的情况下调用相同的控制器,则可以在此块中包含format.html.

在我的application.html.erb中,我有一部分呈现flash消息:

<%= render "layouts/flash_notices" %>

并且该partial包含一个如下所示的div:

<% flash.each do |type, message| %>

<%= type %>: <%= message %>

<% end %>

最后,我创建了一个名为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视图,最后,执行用id ="flash_messages"替换div的内容的javascript.我的原始视图使用flash消息进行更新,所有内容都适用于全世界.

注意:如果您正在使用Bootstrap或其他一些特殊的CSS框架,您可以将该代码包含在js.erb文件的$("#flash_messages").html(""); call.我包含了我的Bootstrap代码,如下所示:

$("#flash_messages').html("")

我知道这个问题是几个月前发布的,但是在搜索这个确切的问题时,响应似乎总是需要通过标头发送flash消息.我想表明还有另一种方法.希望这将有助于我的同伴Rails未来的新手!

2 个回答
  • 我想权衡一下,因为需要将消息传递给头部,这似乎是做Rails应该已经能够做的事情的一种回合方式.

    经过几个小时的搜索后,我意识到我已经通过在控制器中传递以下行来完成需要完成的工作:

    flash[:error] = "My flash message error."
    
    respond_to do |format|
      format.js 
    end
    

    flash [:error]为以下视图设置Flash消息,respond_to意识到我在我的link_to(原始ajax请求)中设置了remote:true:

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

    并作为JavaScript响应链接.如果您仍希望能够在没有远程设置为true的情况下调用相同的控制器,则可以在此块中包含format.html.

    在我的application.html.erb中,我有一部分呈现flash消息:

    <%= render "layouts/flash_notices" %>
    

    并且该partial包含一个如下所示的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视图,最后,执行用id ="flash_messages"替换div的内容的javascript.我的原始视图使用flash消息进行更新,所有内容都适用于全世界.

    注意:如果您正在使用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>")
    

    我知道这个问题是几个月前发布的,但是在搜索这个确切的问题时,响应似乎总是需要通过标头发送flash消息.我想表明还有另一种方法.希望这将有助于我的同伴Rails未来的新手!

    2023-02-04 18:22 回答
  • 首先,感谢全面的问题

    这是一个同样全面的答案:如何使用Ajax请求处理Rail的闪存?


    阿贾克斯

    我会认真看看你的Ajax刷新过程.刷新整个页面是非常低效的,我认为涉及更深层次的问题

    为什么不尝试.js.erbviews文件夹中使用文件,直接通过以下方法处理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中间件处理的.我认为XHR的处理方式与标准HTTP请求不同,因此会阻止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);
    });
    

    2023-02-04 18:22 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有