Подтвердить что ты не робот

Сообщение Rails flash через ajax

Короче говоря, у меня есть кнопка. При щелчке по нему я хочу, чтобы запрос ajax был запущен, который получает flash [: notice] и отображает его в div в $

Вот мой сокращенный вид:

 <input type="button" id="search" value="display"/>

 <div id="notice">

 </div>

Мой запрос ajax в представлении:

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

Мой контроллер:

def HomeController <  ActionController::Base
  def index

  end

  def show
    respond_to do |format|
    format.js {  flash[:notice] = "" + count.to_s + " results found for " + params[:query][:search_key] + "" }
    end
    #render :partial => 'search'
  end
end

Мой show.js.erb

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

$("#content").html("<%=j render partial: "search" %>");

Проблема заключается в том, когда я нажимаю кнопку, уведомление отображается в порядке. Но одно и то же уведомление сохраняется и при следующих кликах. Поиск частично содержит таблицу. Пожалуйста, помогите!

4b9b3361

Ответ 1

Сессия

одно и то же уведомление сохраняется и при следующих кликах

Это вызвано тем, что flash является хранящимся в переменной session Rails:

Вспышка - это особая часть сеанса, которая очищается с каждой запрос. Это означает, что сохраненные там значения будут доступны только в следующий запрос, который полезен для передачи сообщений об ошибках и т.д.

Проблема заключается в том, что, поскольку я не думаю, что ajax считается новым запросом (нужна ссылка для этого), данные будут сохраняться в следующий раз, когда вы запрашиваете через HTTP.

-

Fix

Сначала я попытался бы это сделать:

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

Основная проблема заключается в том, что вы обрабатываете переменную flash в JS, используя препроцессор ERB. Это проблема, так как это означает, что вы не сможете использовать прекомпиляцию активов, чтобы помочь ей работать.

Посмотрев на этот вопрос, почему бы не попробовать использовать after_filter callback, например:

#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

-

Обновление

Вы должны включить функциональность success в свой show.js.erb:

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

Это означает, что вы можете удалить весь вызов ajax из application.js и заменить на remote: true для своей формы поиска:

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

Причина этого в том, что, когда вы используете блок ответа format.js, Rails загрузит файл [action].js.erb в ваши представления. Учитывая, что это происходит только после завершения действия, это эквивалентно функции success вашего ajax.

Посредством этого вы сможете удалить всю функцию ajax из application.js и заменить ее версией UJS, как описано выше

Ответ 2

Вот пример, который я получил, благодаря ответу Рича Пек. Мне нужно было использовать flash.now, чтобы убедиться, что уведомление о вспышке не сохранилось.

Триггер AJAX в представлении:

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

Контроллер:

# 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

Представленный вид:

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

где в макете отображается уведомление о вспышке:

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


# app/views/shared/_notice_banner.html.erb
<div data-alert class="alert-box">
  <%= notice %>
  <a href="#" class="close">&times;</a>
</div>