Как вы справляетесь с Flash Rail с Ajax-запросами? - PullRequest
75 голосов
/ 14 декабря 2008

Я очень доволен решением , которое я придумал. По сути, у меня есть вспомогательный метод, который перезагружает флэш-память, а затем у меня есть after_filter, который очищает флэш-память, если запрос xhr. У кого-нибудь есть более простое решение, чем это?

Обновление: Приведенное выше решение было переписано в Rails 1.x и больше не поддерживается.

Ответы [ 15 ]

3 голосов
/ 15 февраля 2011

На основании ответа гудлейка:

class ApplicationController < ActionController::Base
  after_filter :flash_to_headers

def flash_to_headers
  return unless request.xhr?
  response.headers['X-Message'] = flash_message
  response.headers["X-Message-Type"] = flash_type

  flash.discard # don't want the flash to appear when you reload page
end

private

def flash_message
  [:error, :warning, :notice].each do |type|
    return flash[type] unless flash[type].blank?
  end
end

def flash_type
  [:error, :warning, :notice].each do |type|
    return type unless flash[type].blank?
  end
end

Затем в вашем application.js (если вы используете нативные помощники Prototype в Rails) добавьте:

Ajax.Responders.register({
onComplete: function(event, request) {
   var msg = request.getResponseHeader('X-Message');
   var type = request.getResponseHeader('X-Message-Type');
   showAjaxMessage(msg, type); //use whatever popup, notification or whatever plugin you want
   }
});
1 голос
/ 15 января 2013

Я создаю движок, который включает некоторое поведение для application_controller для отправки флеш-сообщения в заголовке ответа, как предлагают некоторые из вас.

https://github.com/bonzofenix/flajax

1 голос
/ 11 марта 2009

Другим способом было бы обновить / отобразить div «messages» с сообщением от вашего обработчика Ajax-запросов «OnFailure». Это дает вам возможность показывать эти флэш-сообщения с требуемым эффектом. Я использовал это

 render :text => "Some error happened", :status => 444

в JavaScript

 new AjaxRequest(...

  ,
   OnFailure:function(transport) {
      $("#notice").update(transport.responseText);
     // show the message  
   }

);

НТН

0 голосов
/ 02 июля 2013

Если вы хотите использовать вызовы AJAX, redirect_to не должен использоваться в контроллере. Скорее, флэш-сообщение должно быть явно обозначено:

В вашем контроллере:

respond_to :js

def your_ajax_method
  flash[:notice] = 'Your message!'
end

В представлении, названном your_ajax_method_in_the_controller

your_ajax_method_in_the_controller.js.haml

:plain
  $("form[data-remote]")
    .on("ajax:success", function(e, data, status, xhr) {
      $('.messages').html("#{escape_javascript(render 'layouts/messages')}");
      setTimeout(function(){ $(".alert").alert('close') }, 5000);
    })

Пожалуйста, обратите внимание, что сообщений класс является точкой привязки для визуализации сообщений. Этот класс должен присутствовать в вашем представлении или макете приложения. Если вы используете ERB, строка становится $('.messages').html("<%= j(render 'layouts/messages') %>");

Приведенный выше JavaScript, встроенный в HAML / ERB, является ключом для отображения флэш-сообщений при использовании AJAX. Все остальные компоненты остаются неизменными для вызовов не AJAX.

Вы можете использовать your_ajax_method_in_the_controller.js.coffee или обычный .js, но тогда переменные rails не будут доступны для JS / Coffee. Несмотря на то, что здесь я не использую переменные, я предпочитаю заключать JS в HAML, чтобы поддерживать согласованную кодовую базу.

Я использую Twitter Bootstrap для оформления сообщений, поэтому $(".alert").alert('close') скрывает уведомление. А вот сообщений частично:

Макеты / _messages.html.haml

- flash.each do |name, msg|
  - if msg.is_a?(String)
    .alert-messages
      %div{class: "alert alert-#{name == :notice ? "success" : "error"} fade in"}
        %a.close{"data-dismiss" => "alert"} 
          %i.icon-remove-circle
        = content_tag :div, msg, id: "flash_#{name}"

На всякий случай, CSS для предупреждений ниже

.alert-messages {
  position: fixed;
  top: 37px;
  left: 30%;
  right: 30%;
  z-index: 7000;
}
0 голосов
/ 15 декабря 2008

Единственное улучшение, которое я могу придумать, это сделать по умолчанию page.reload_flash (не нужно помещать его в каждый файл rjs, и сделать его недействительным, если вы не хотите перезагружать flash, что-то вроде page.keep_flash.

Я бы не знал, с чего начать, но зная некоторые рельсы, я уверен, что это не так сложно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...