programing

Ajax 요청이 있는 Rail의 플래시를 어떻게 처리합니까?

yellowcard 2023. 3. 11. 08:48
반응형

Ajax 요청이 있는 Rail의 플래시를 어떻게 처리합니까?

저는 제가 생각해낸 해결책에 꽤 만족합니다.기본적으로 플래시를 인라인으로 새로고침하는 도우미 메서드가 있으며 요구가 xhr일 경우 플래시를 클리어하는 after_filter가 있습니다.그것보다 더 간단한 해결책을 가진 사람이 있나요?

업데이트: 상기 솔루션은 Rails 1.x에 기재되어 있으며, 더 이상 지원되지 않습니다.

after_filter 블록을 사용하여 응답 헤더에 플래시 메시지를 저장하고 javascript를 사용하여 표시할 수도 있습니다.

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에서 글로벌 에이잭스 핸들러를 추가합니다.jquery의 경우 다음과 같은 작업을 수행합니다.

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

alert()를 javascript flash 함수로 대체하거나 jGrowl을 사용해 보십시오.

다음은 Rails 3.2에서 테스트된 jQuery에서 작동하도록 수정된 @emzero 기반 버전입니다.

application_controller.displus

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

어플.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.disc.haml

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

이것은 js 응답에 필요합니다.

RSJ를 사용하는 경우:

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

jQuery를 사용하는 경우:

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

이렇게 했는데..

컨트롤러:

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

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

post.contract.erb

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

다른 것 위에 쌓는 것 위에 쌓기

(플래시 객체 전체를 JSON으로 전달하여 플래시 객체 전체를 브라우저에서 재구성할 수 있습니다.이를 통해 Rails에 의해 여러 개의 플래시 메시지가 생성된 경우 모든 플래시 메시지가 표시되도록 할 수 있습니다.)

#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
}

에게 한 것은 ★★★★★★★★★★★★★★★★★★★★★★★★★★★.flash.now[:notice]현재 액션에서만 사용할 수 있으며 다음 액션에서는 사용할 수 없습니다.매뉴얼은 http://api.rubyonrails.com/classes/ActionController/Flash/FlashHash.html#M000327 에서 보실 수 있습니다.

다음과 같이 컨트롤러에 메시지를 할당합니다.

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

app/views/layouts/application.js.erb - Ajax 요청 레이아웃.여기에서는 간단하게

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

또는 그리터를 사용한 리치 애니메이션을 이용하실 수 있습니다.http://boedesign.com/demos/gritter/

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

Gudleik 답변에 근거합니다.

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

그런 다음 응용 프로그램.js(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
   }
});

플래시 메시지를 자동으로 쿠키로 인코딩하는 Untruptive Flash라고 불리는 보석이 있습니다.클라이언트 엔드의 Javascript는 플래시를 체크하고 원하는 방식으로 표시합니다.이는 일반 요구와 Ajax 요구 모두에서 심리스하게 동작합니다.

S의 해서 'S'가 'S'로 되어 있는 경우를 했습니다.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

});

버전(복수 플래시 알림 및 특수 문자 UTF-8 인코딩 사용)은 다음과 같습니다.

내부 Application Controller:

after_filter :flash_to_headers
def flash_to_headers
  return unless request.xhr?
  [:error, :warning, :notice].each do |type|
    if flash[type]
      response.headers["X-Ajax-#{type.to_s.humanize}"] = flash[type]
    end
  end
  flash.discard
end

my coffee-script (트위터 부트스트랩 버전):

css_class = {
    Notice: 'success',
    Warning: 'warning',
    Error: 'error'
}
$(document).ajaxComplete (event, request) ->
  for type in ["Notice", "Warning", "Error"]
    msg = request.getResponseHeader("X-Ajax-#{type}")
    if msg?
      $('#notices').append("<div class=\"alert #{css_class[type]}\">#{decodeURIComponent(escape(msg))}</div>")

또 다른 방법은 Ajax 요청 "OnFailure" 핸들러로부터의 메시지로 "notice" div를 업데이트/표시하는 것입니다.이러한 플래시 메시지를 필요한 효과와 함께 표시할 수 있습니다.이거 썼어

렌더 : text = > "Some error occurred", : status = > 444

Javascript에서

새로운 Ajax Request(...)

,On Failure: 함수(트랜스포트) {$("#notice").update(transport.responseText);
// 메시지 표시}
);

HTH

application_controller에 대한 동작을 포함하는 엔진을 구축하여 응답 헤더에 플래시 메시지를 보냅니다.

https://github.com/bonzofenix/flajax

유일하게 생각할 수 있는 개선사항은 page.reload_flash를 디폴트로 하는 것입니다(모든 rjs 파일에 저장할 필요는 없습니다).플래시를 새로고침하지 않을 경우 페이지와 같은 형식으로 지정합니다.keep_flash 입니다.

어디서부터 시작해야 할지 모르겠지만 몇몇 레일을 알고 있으니 그렇게 어렵지 않을 거예요.

AJAX 콜을 사용하는 경우 redirect_to를 컨트롤러에서 사용하지 마십시오.대신 플래시 메시지는 다음과 같이 명시해야 합니다.

your_controller 내:

respond_to :js

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

your_ajax_method_in_the_controller에 의해 명명된 뷰에서

당신의_controller.controller.haml에 있는_controller_controller.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') %>");

HAML/ERB에 내장된 위의 JavaScript는 AJAX를 사용할 때 플래시 메시지를 표시하는 키입니다.다른 모든 컴포넌트는 AJAX 이외의 콜에서는 동일하게 유지됩니다.

하면 .your_ajax_method_in_the_controller.js.coffeeJS/Coffee의 .js입니다.여기서는 변수를 사용하지 않지만 일관된 코드베이스를 유지하기 위해 JS를 HAML로 랩하는 것을 선호합니다.

에 Twitter Bootstrap은 Twitter Bootstrap입니다.$(".alert").alert('close')공지를 희미하게 하다.다음은 일부 메시지입니다.

레이아웃/_layouts.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;
}

언급URL : https://stackoverflow.com/questions/366311/how-do-you-handle-rails-flash-with-ajax-requests

반응형