सवाल आप अजाक्स अनुरोधों के साथ रेल के फ्लैश को कैसे संभालेंगे?


मैं बहुत खुश हूँ समाधान कि मैं साथ आया था। असल में, मेरे पास एक सहायक विधि है जो फ़्लैश इनलाइन को फिर से लोड करती है, और उसके बाद मेरे पास एक_फिल्टर है जो अनुरोध xhr होने पर फ्लैश को साफ़ करता है। क्या किसी के पास उससे सरल समाधान है?

अद्यतन करें: उपरोक्त समाधान रेल 1.x में वापस लिखा गया था और अब समर्थित नहीं है।


74
2017-12-14 08:40


मूल


मुझे आपका समाधान पसंद है .. after_filter { flash.discard if request.xhr? } - Peter Ehrlich


जवाब:


आप बाद वाले फ़ाइल ब्लॉक का उपयोग कर प्रतिक्रिया शीर्षलेखों में फ्लैश संदेश भी संग्रहीत कर सकते हैं और उन्हें जावास्क्रिप्ट का उपयोग करके प्रदर्शित कर सकते हैं:

class ApplicationController < ActionController::Base
after_filter :flash_to_headers

def flash_to_headers
  return unless request.xhr?
  response.headers['X-Message'] = flash[:error]  unless flash[:error].blank?
  # repeat for other flash types...

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

और application.js में एक वैश्विक AJAX हैंडलर जोड़ें। Jquery के लिए ऐसा कुछ करें:

$(document).ajaxError(function(event, request) {
  var msg = request.getResponseHeader('X-Message');
  if (msg) alert(msg);
});

अपने स्वयं के जावास्क्रिप्ट फ़्लैश फ़ंक्शन के साथ अलर्ट () को बदलें या jGrowl आज़माएं।


61
2018-04-28 12:43



इसके अतिरिक्त, आप संदेश प्रकार को स्टोर कर सकते हैं: response.headers['X-Message-Type'] = flash_type (जबकि flash_type सबसे महत्वपूर्ण प्रकार (त्रुटि> सफलता> नोटिस) देता है। इसके अलावा, आप इसका उपयोग कर सकते हैं ajaxComplete फिर सफलता के मामलों को शामिल करने के लिए: $(document).ajaxComplete(function(e, request, opts) { fireFlash(request.getResponseHeader('X-Message'), request.getResponseHeader('X-Message-Type')); }); - crispy
यदि आपका रेल एप्लिकेशन AJAX अनुरोध करने के लिए प्रोटोटाइप का उपयोग कर रहा है, तो पिछले jquery हैंडलर काम नहीं करेगा। आपको संबंधित प्रोटोटाइप हैंडलर का उपयोग करने की आवश्यकता होगी। ऊपर मेरा जवाब देखें। - emzero
application.js के शीर्ष पर टिप्पणियां क्यों कहती हैं कि कोड जोड़ने के लिए सलाह नहीं दी जाती है? - Steve
JGrowl की सिफारिश करने के लिए +1। - user456584


और यहां मेरा संस्करण @emzero पर आधारित है, जिसमें jQuery के साथ काम करने के लिए संशोधनों के साथ रेलवे 3.2 पर परीक्षण किया गया है

application_controller.rb

class ApplicationController < ActionController::Base
    protect_from_forgery

    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.to_s

        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
end

application.js

// FLASH NOTICE ANIMATION
var fade_flash = function() {
    $("#flash_notice").delay(5000).fadeOut("slow");
    $("#flash_alert").delay(5000).fadeOut("slow");
    $("#flash_error").delay(5000).fadeOut("slow");
};
fade_flash();

var show_ajax_message = function(msg, type) {
    $("#flash-message").html('<div id="flash_'+type+'">'+msg+'</div>');
    fade_flash();
};

$(document).ajaxComplete(function(event, request) {
    var msg = request.getResponseHeader('X-Message');
    var type = request.getResponseHeader('X-Message-Type');
    show_ajax_message(msg, type); //use whatever popup, notification or whatever plugin you want
});

लेआउट: application.html.haml

        #flash-message
            - flash.each do |name, msg|
                = content_tag :div, msg, :id => "flash_#{name}"

29
2018-04-16 01:14



यह रेल पर भी काम करता है 3.1.0। धन्यवाद विक्टर, मेरे लिए बॉक्स से बाहर काम किया। - LearningRoR
ग्रेट संकलन, हालांकि "$ (" # फ्लैश-मैसेज "नहीं होना चाहिए) AJAXComplete (फ़ंक्शन (ईवेंट, अनुरोध)" $ "(दस्तावेज़)" होना चाहिए? - nullnullnull
किसी कारण से, 'जब तक फ्लैश [टाइप] .blank?' कुछ परिस्थितियों में ठीक से काम नहीं करता है। कोई चमक नहीं होने वाली क्रिया वाक्य 'त्रुटि, चेतावनी, नोटिस' प्रस्तुत करेगी। मैंने लाइन का उपयोग करके जेएस में इसे पैच किया, 'अगर (msg! = "त्रुटि, चेतावनी, नोटिस") show_ajax_message (msg, टाइप करें)', लेकिन यह स्पष्ट रूप से एक हैकी समाधान है। हालांकि, मैं समस्या का वास्तविक कारण नहीं समझ सकता। - nullnullnull
[:error, :warning, :notice].each {} वापसी की स्थिति पूरी नहीं होने पर सरणी लौटाती है, इसलिए इस कोड को समायोजित करने की आवश्यकता है .. लेकिन अन्यथा, सहायक। - radixhound
यदि स्ट्रिंग "त्रुटि, चेतावनी, नोटिस" को वापस करने के लिए कोड को फिर से काम नहीं किया गया है और साथ ही ट्विटर-बूटस्ट्रैप के साथ अच्छा खेलना है gist.github.com/hbrandl/5253211 - Hartwig


जेएस प्रतिक्रिया में इसकी आवश्यकता है

यदि आप आरएसजे का उपयोग कर रहे हैं:

page.replace_html :notice, flash[:notice]
flash.discard

यदि आप jQuery का उपयोग कर रहे हैं:

$("#flash_notice").html(<%=escape_javascript(flash.delete(:notice)) %>');

15
2018-01-08 11:28



ऐसा लगता है कि रेल 3.1 में आपको उपयोग करने की ज़रूरत है flash.discard(:notice) बजाय flash.delete(:notice) - Adrian Macneil


मैंने इसे इस तरह से किया ..

नियंत्रक:

respond_to do |format|
    flash.now[:notice] = @msg / 'blah blah...'
    format.html 
    format.js
  end

राय:

<div id='notice'>
    <%= render :partial => 'layouts/flash' , :locals => { :flash => flash } %>
</div>        

लेआउट / _flash.html.erb

<% flash.each do |name, msg| %>
            <div class="alert-message info"> 
                <a class="close dismiss" href="#">x</a> 
                <p><%= msg %></p>
            </div>
<% end %>

post.js.erb

$("#notice").html("<%= escape_javascript(render :partial => 'layouts/flash' , :locals => { :flash => flash }).html_safe %>");

14
2018-01-15 21:40



आपके नियंत्रक में, मैं एक टाइपो देख सकता हूं flash.now[:notice]= @msg / 'blah blah..' मैं भी उत्सुक था, आप पथ एजे / संपत्ति / जावास्क्रिप्ट में post.js.erb डाल देंगे? - TheMouseMan
post.js.erb इस मामले में नियंत्रकों के दृश्य फ़ोल्डर में जाता है, इसके "विचार / पोस्ट / post.js.erb"। msg / "ब्ला ब्लाह" मेरा मतलब था संदेश या कुछ यादृच्छिक संदेश जैसे "ब्ला ब्लाह" - dbKooper
मेरे लिए काम किया, धन्यवाद! - Stef Hej


दूसरों के शीर्ष पर बिल्डिंग -

(हम पूरी फ्लैश ऑब्जेक्ट को जेएसओएन के रूप में पास करते हैं, जिससे हमें ब्राउजर में पूरी फ्लैश ऑब्जेक्ट का पुनर्निर्माण करने में मदद मिलती है। इसका उपयोग यह सुनिश्चित करने के लिए किया जा सकता है कि रेल द्वारा कई फ्लैश संदेश उत्पन्न किए जाने पर सभी फ़्लैश संदेश प्रदर्शित होते हैं।)

#application_controller.rb
class ApplicationController < ActionController::Base
  after_filter :flash_to_headers

  def flash_to_headers
    if request.xhr?
      #avoiding XSS injections via flash
      flash_json = Hash[flash.map{|k,v| [k,ERB::Util.h(v)] }].to_json
      response.headers['X-Flash-Messages'] = flash_json
      flash.discard
    end
  end
end
//application.js
$(document).ajaxComplete(function(event, request){
  var flash = $.parseJSON(request.getResponseHeader('X-Flash-Messages'));
  if(!flash) return;
  if(flash.notice) { /* code to display the 'notice' flash */ $('.flash.notice').html(flash.notice); }
  if(flash.error) { /* code to display the 'error' flash */ alert(flash.error); }
  //so forth
}

9
2017-09-14 10:11



Thnx। मैंने इसे पसंद करने के लिए application.js में फ़ंक्शन संशोधित किया $.each( $.parseJSON(request.getResponseHeader('X-Flash-Messages')), function(key,value){ flash_message(key,value) }); यदि आपके पास फ़्लैश और संदेश पैराम प्रकार के साथ फ्लैश संदेश दिखाने के लिए जेएस फ़ंक्शन है - Rahul garg


ऐसा लगता है कि आपको क्या चाहिए flash.now[:notice], जो केवल वर्तमान कार्रवाई में उपलब्ध है और अगले में नहीं। आप यहां प्रलेखन को देख सकते हैं: http://api.rubyonrails.com/classes/ActionController/Flash/FlashHash.html#M000327


6
2018-01-01 18:51



अरे, मुझे यह पसंद है! और किसी की नहीं ? : एस - Bachet
@le_Daf: उपयोग करना flash.now एक अलग समस्या का समाधान है। की सामग्री flash.now अजाक्स कॉलबैक द्वारा वर्तमान पृष्ठ में जादुई रूप से डाला नहीं जाता है। - Confusion
फ़्लैश के बजाय flash.eventually कहा जाना चाहिए था .now;) - Deborah


इस तरह नियंत्रक में संदेश असाइन करें:

  flash.now[:notice] = 'Your message'

ऐप / विचार / लेआउट / application.js.erb - अजाक्स अनुरोधों के लिए लेआउट। यहां आप बस उपयोग कर सकते हैं

  <%= yield %>
  alert('<%= escape_javascript(flash.now[:notice]) %>'); 

या gritter का उपयोग कर कुछ समृद्ध एनिमेशन के साथ: http://boedesign.com/demos/gritter/

  <%= yield %>
  <% if flash.now[:notice] %>
    $.gritter.add({
      title: '--',
      text: '<%= escape_javascript(flash.now[:notice]) %>'
    });
  <% end %>

5
2017-08-05 11:08





गुडलिक उत्तर के आधार पर:

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 पर (यदि आप रेल मूल प्रोटोटाइप हेल्पर्स का उपयोग कर रहे हैं) जोड़ें:

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
   }
});

3
2018-02-15 18:09





एक मणि कहा जाता है अविभाज्य फ्लैश जो स्वचालित रूप से एक कुकी में फ़्लैश संदेशों को एन्कोड करता है। क्लाइंट एंड पर एक जावास्क्रिप्ट फ्लैश के लिए चेक करता है और इसे जिस तरह से आप चाहते हैं उसे प्रदर्शित करता है। यह सामान्य और AJAX अनुरोध दोनों में निर्बाध रूप से काम करता है।


3
2018-03-26 01:49



मेरे लिए सभी मुद्दों को हल किया। - W.M.


मैंने कुछ मामलों को ठीक करने के लिए विक्टर एस के जवाब को संशोधित किया flash[type].blank? टिप्पणी में कुछ लोगों द्वारा नोट किया गया काम नहीं किया।

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.to_s

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

private

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

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

फिर बाकी वही है

// FLASH NOTICE ANIMATION

var fade_flash = function() {
    $(".flash_notice").delay(5000).fadeOut("slow");
    $(".flash_alert").delay(5000).fadeOut("slow");
    $(".flash_error").delay(5000).fadeOut("slow");
};

var show_ajax_message = function(msg, type) {
    $(".flash_message").html('<div class="flash_'+type+'">'+msg+'</div>');
    fade_flash();
};

$( document ).ajaxComplete(function(event, request) {
    var msg = request.getResponseHeader('X-Message');
    var type = request.getResponseHeader('X-Message-Type');
    show_ajax_message(msg, type); //use whatever popup, notification or whatever plugin you want

});

3
2017-09-07 23:37