Warum verschwindet die Flash-Nachricht nicht?

78

Ich führe eine Ausnahmebehandlung in meinem Controller durch. Wenn eine Ausnahme ausgelöst wird: Aktion erstellen, werde ich in die Aktion: Neue Aktion rendern und eine Flash-Nachricht anzeigen.

Alles funktioniert einwandfrei, ich kann die Flash-Nachricht sehen, wenn eine Ausnahme abgefangen wird, aber wenn ich auf eine andere Seite umleitung (mit der Hand klicken) , ist die Flash-Nachricht immer noch hier . Dann leite ich auf eine andere Seite um ( der zweite Klick) , die Nachricht könnte verschwinden.

Wer weiß was der Grund ist?

Mein Controller-Code:

class MessagesController < ApplicationController
  rescue_from Exception, :with => :render_new

  def new
  end

  def create
  end

private
  def render_new
    flash[:alert] = t("uploading_error")
    render :action => :new
  end
end

Mein Layoutcode (Haml):

%body
  #content
    - unless flash[:alert].blank?
      #alert= flash[:alert]
Jimmy Huang
quelle

Antworten:

162

Ersetzen

flash[:alert] = t("uploading_error")

mit

flash.now.alert = t("uploading_error")

und sehen, ob das das Ergebnis ist, das Sie erwarten?

flash[:alert]bleibt für die nächste Seite erhalten (daher verschwindet sie erst bei der zweiten Weiterleitung); wird aber flash.now.alertnur für die aktuelle Seite angezeigt.

Zabba
quelle
Hervorragende Lösung und Link! Danke zabba!
Jimmy Huang
1
Jetzt weiß ich mehr über den Blitz und den Blitz. Wenn ich also redirect_to anstelle von render verwende, ist die Verwendung von Flash ebenfalls kein Problem.
Jimmy Huang
1
Zu Ihrer Information: Die Verbindung ist unterbrochen. Aber ohne den Link zu sehen, muss ich zugeben, dass ich neugierig bin, warum flash.now [: alert] nicht die Standardeinstellung ist.
Reise
Ihre Website kann
vorerst
1
Rails Doc hat auch einige anständige Informationen über Flash und Flash.now
Zabba
45

Die Entscheidung zwischen flash.now und normalem Flash ist ein Schmerz im Arsch und meiner Erfahrung nach ziemlich zerbrechlich. Ich verwende einen normalen Blitz und ändere dann meinen Teil, der die Blitze anzeigt, um den Inhalt jedes Blitzes zu löschen, nachdem der Benutzer ihn gesehen hat. Ich denke das ist besser weil

a) Sie müssen nicht darüber nachdenken

b) "Hat der Benutzer es gesehen?" (dh "Wurden die Blitze teilweise gerendert?") ist das beste Kriterium für die Entscheidung, ob der Blitz gelöscht werden soll oder nicht, und keine Logik in Ihrer App.

Mein Flash-Teil sieht so aus - ich benutze auch ein bisschen jquery, um die Blitze hervorzuheben (dh sie für eine Sekunde gelb blinken zu lassen):

<div id="flashes">

  <% if flash[:notice] %>
    <p id="flash_notice" class="messages notice"><%= flash[:notice] %></p>
    <%= javascript_tag "$('#flash_notice').effect('highlight',{},1000);" %>
  <% end %>

  <% if flash[:error] || flash[:errors] %>
    <p id="flash_errors" class="messages errors"><%= flash[:error] || flash[:errors] %></p>
    <%= javascript_tag "$('#flash_errors').effect('highlight',{},1000);" %>
  <% end %>

  <% flash[:error] = flash[:errors] = flash[:notice] = nil %>
</div>
Max Williams
quelle
Vielleicht eine dumme Frage, aber ist es möglich, dass dadurch ein weiterer Blitz gelöscht wird, der gerade gerendert wird?
Bradford
@Bradford - ich glaube nicht: Ich lösche nur die drei Flash-Tasten, die ich gerendert habe. Es gibt keine Möglichkeit, dass sie gelöscht werden, ohne gerendert zu werden, und nichts kann zwischen ihnen passieren, wenn sie gerendert und gelöscht werden, da das Löschen im selben Teil erfolgt.
Max Williams
Spät zum Spiel, aber ich liebe das.
Dan Barron
1
Ich habe es gerade versucht. Ich denke, flash.discard (a_single_key) ist besser, weil das Setzen des Werts auf nil den Schlüssel nicht aus Flash entfernt. Infolgedessen könnte eine leere Nachricht für den gelöschten Schlüssel angezeigt werden.
TrongBang
34

Eine Alternative ist die Verwendung von flash.clear am Ende des Teils wie folgt :

<% if !flash.empty? %>
  <div class="flash-messages-container">
    <% flash.each do |name, msg| %>
      <% if msg.is_a?(String) && [:success, :info, :error, :warning].include?(name) %>
        <div class="flash-message" data-type="<%= name %>" >
          <%= msg %>
        </div>
      <% end %>
    <% end %>
  </div>
  <% flash.clear %>
<% end %>
CoderDave
quelle
Flash.clear ist viel sauberer als <% Flash [: Fehler] = Flash [: Fehler] = Flash [: Hinweis] = Null%>
Kevin Zych
Nach meiner Erfahrung ist dies der beste Weg, es sei denn, Sie benötigen Ihre Flash-Nachrichten, um fortzufahren. Ich weiß nicht, warum Vorlagen (vielleicht die Gerüste?) Nicht standardmäßig mit flash.clear geliefert werden.
Ravenstine
2
flash.clear funktioniert bei mir nicht. Flash verschwindet immer noch nicht
Nimish
1

Auch dies funktioniert nicht ...... Bestimmte Arten von Ausnahmen wie Syntaxfehler ... verhindern, dass Cookies, Flashs oder Parameter vom Controller zur Ansicht übertragen werden. Sie können nur einen Sitzungsschlüssel verwenden und ihn nach Anzeige des Fehlers löschen.

Versuchen Sie Ihre Lösung mit einem Syntaxfehler ... Sie sollten sehen, dass Ihre Nachricht auf der umgeleiteten Seite nur mit einem Sitzungsschlüssel angezeigt wird.

surtep
quelle
1

Früher hatte ich das gleiche Problem, aber jetzt dadurch gelöst:
Versuchen Sie dies in Ihrem Code

<script type="text/javascript">
  $(document).ready(function(){
    setTimeout(function(){
    $('#flash').fadeOut();
    }, 2000);
  })
</script>
Nimish
quelle