2011-01-06 12 views
72

Sto facendo un po 'di gestione delle eccezioni nel mio controller, quando c'è un'eccezione lanciata: create action, renderò alla: nuova azione e mostrerò un messaggio flash.Perché il messaggio flash non scomparirà?

Tutto funziona bene, posso vedere il messaggio flash quando eccezione catturato, ma quando ho il reindirizzamento (click handly) altra pagina, il messaggio flash ancora qui. Quindi reindirizzamento a un'altra pagina (il secondo clic manuale), il messaggio potrebbe scomparire.

Chi sa qual è il motivo?

Il mio codice di controllo:

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 

Il mio codice di layout (Haml):

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

risposta

145

Sostituire

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

con

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

e vedi se questo è il risultato che ti aspetti?

flash[:alert] rimarrà in giro per la pagina successiva (quindi scompare solo al secondo reindirizzamento); ma flash.now[:alert] verrà visualizzato solo per la pagina corrente.

+0

Ottima soluzione e il link! Grazie, zabba! –

+1

Ora so di più sul flash e flash.now. Quindi, se l'utente reindirizza_to anziché renderizzare, utilizzare il flash non sarà un problema. –

+1

FYI: link is broke. Ma senza vedere il link, devo ammettere che sono curioso perché flash.now [: alert] non è predefinito. – Trip

45

Decidere tra flash.now e flash regolari è un rompicoglioni e piuttosto fragile nella mia esperienza. Uso il flash normale e poi modifico il mio partial che visualizza i flash per cancellare il contenuto di ciascun flash dopo che l'utente lo ha visto. Credo che questo è meglio perché

a) non devi pensarci

b) "ha l'utente visto?" (cioè "il rendering parziale dei flash è stato eseguito?") è il miglior criterio per decidere se cancellare o meno il flash, piuttosto che qualsiasi logica nella tua app.

mio flash sguardi parziali come questo - Io uso anche un po 'di jQuery solo evidenziare i flash (cioè renderli lampo giallo per un secondo):

<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> 
+1

Ogni volta che svuoti i messaggi flash, cool! –

+2

Sicuramente merita e upvote. –

+0

Forse una domanda stupida, ma è possibile che questa operazione cancelli un altro flash che sta per essere renderizzato? – Bradford

1

Anche questo non funziona .... ..dove tipi di eccezioni come errori di sintassi ... impediranno il trasferimento di qualsiasi tipo di cookie, flash o parametri dal controller alla vista. L'unica opzione è usare una chiave di sessione e poi cancellarla dopo aver mostrato l'errore.

Prova la soluzione con un errore di sintassi ... dovresti vedere che il tuo messaggio non verrà visualizzato nella pagina reindirizzata con nient'altro che con una chiave di sessione .....

30

Un'alternativa è quella di utilizzare flash.clear alla fine del parziale, in questo modo:

<% 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 %> 
+0

flash.clear è molto più pulito di <% flash [: errore] = flash [: errori] = flash [: avviso] = nil%> –

+0

Secondo la mia esperienza, questo è il modo migliore per farlo a meno che non sia necessario il messaggio flash persistere. Non so perché i modelli (forse gli scaffold fanno?) Non vengono forniti con flash.clear per impostazione predefinita. – Ravenstine

+2

flash.clear non funziona per me. Il flash non sta ancora scomparendo – indb

1

precedenza avevo lo stesso problema, ma ora risolto attraverso questo:
Prova questa nel codice

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