Rails flash notice tramite ajax

Per farla breve, ho un pulsante. Facendo clic su di esso, voglio che venga avviata una richiesta di ajax che riceve il flash [: notice] e la visualizza in un div in $

Ecco la mia vista abbreviata:

 

La mia richiesta Ajax nella vista:

 $("#search").submit(function(){ $.ajax({ type: "POST", url: //url to my show action success: function(data){ /*$("#notice").html(""); $("#content").html(data);*/ } }); return false; }); 

Il mio controller:

 def HomeController  'search' end end 

Il mio show.js.erb

 #app/views/dashboard_home/show.js.erb $("#notice").html(""); $("#content").html(""); 

Il problema è quando clicco sul pulsante, l’avviso viene visualizzato bene. Ma lo stesso avviso persiste anche nei clic successivi. Il partial di ricerca contiene la tabella Please help!

sessioni

lo stesso avviso persiste anche nei clic successivi

Ciò è causato dal fatto che il flash viene memorizzato nella variabile di session di Rails :

Il flash è una parte speciale della sessione che viene cancellata ad ogni richiesta. Ciò significa che i valori memorizzati saranno disponibili solo nella richiesta successiva, utile per trasmettere messaggi di errore, ecc.

Il problema è che siccome non penso che ajax conta come una nuova richiesta (bisogno di riferimento per questo), i dati continueranno a essere inoltrati la prossima volta che richiedi tramite HTTP.

fissare

Inizialmente proverei questo:

 def show respond_to do |format| format.js { flash[:notice] = "my secret number "+rand(0,5)+" !" } end end 

Il problema principale che hai è che stai elaborando la variabile flash nel tuo JS usando il preprocessore ERB . Questo è un problema in quanto significa che non sarai in grado di utilizzare la precompilazione delle risorse per farlo funzionare.

Dopo aver esaminato questa domanda , perché non provare a utilizzare il callback after_filter , in questo modo:

 #app/controllers/home_controller.rb Class Home < ActionController::Base after_filter { flash.discard if request.xhr? }, only: :show def show respond_to do |format| format.js { flash[:notice] = "my secret number "+rand(0,5)+" !" } end end end 

-

Aggiornare

Dovresti includere la funzionalità di success nel tuo show.js.erb :

 #app/views/home/show.js.erb $("#notice").html("<%= flash[:notice] %>"); 

Ciò significa che puoi rimuovere l'intera chiamata ajax da application.js e sostituirla con il remote: true per il tuo modulo di ricerca:

 #app/views/search/index.html.erb <%= form_tag home_show_path, remote: true %> 

Il motivo per cui questo funziona è perché quando si utilizza il blocco risposta format.js , Rails caricherà il file [action].js.erb nelle viste. Considerando che ciò accade solo dopo che l'azione è stata completata, è equivalente alla funzione di success della tua ajax.

In questo modo, sarai in grado di rimuovere l'intera funzione Ajax dal tuo application.js e sostituirla con la versione UJS, come descritto sopra

Ecco un esempio che ho lavorato, grazie alla risposta di Rich Peck. Avevo bisogno di usare flash.now per assicurarmi che l’avviso flash non persistesse.

Trigger AJAX nella vista:

 <%= link_to "Email report", users_path, remote: true %> 

controller:

 # app/controllers/users_controller class UsersController < ApplicationController def index # do some things here respond_to do |format| format.js { flash.now[:notice] = "Here is my flash notice" } end end end 

Vista resa:

 # app/views/users/index.js.erb $("#flash").html('<%= j render partial: "shared/notice_banner" %>'); 

dove l'avviso flash è visualizzato nel layout:

 # app/views/layouts/application.html.erb 
<% if notice.present? %> <%= render partial: "shared/notice_banner" %> <% end %>
# app/views/shared/_notice_banner.html.erb
<%= notice %> ×