복붙노트

[RUBY-ON-RAILS] 어떻게 Ajax 요청과 레일의 플래시를 처리하나요?

RUBY-ON-RAILS

어떻게 Ajax 요청과 레일의 플래시를 처리하나요?

내가 생각 해낸하는 솔루션을 꽤 행복 해요. 기본적으로, 요청이 XHR 경우 다시로드 플래시 인라인, 그리고 나는 플래시에서 분명 after_filter을하는 도우미 메서드가 있습니다. 누구보다 간단한 해결책이 있습니까?

업데이트 : 레일 1.x에서 다시 작성되지 않았으며 더 이상 지원 위의 솔루션입니다.

해결법

  1. ==============================

    1.또한 after_filter 블록을 사용하여 응답 헤더에있는 플래시 메시지를 저장하고 자바 스크립트를 사용하여 표시 할 수 있습니다 :

    또한 after_filter 블록을 사용하여 응답 헤더에있는 플래시 메시지를 저장하고 자바 스크립트를 사용하여 표시 할 수 있습니다 :

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

    자신의 자바 스크립트 플래시 기능과 경고 ()를 교체하거나 jGrowl을 시도해보십시오.

  2. ==============================

    2.그리고 여기 내 버전은 레일 3.2에서 테스트 jQuery로 작업에 대한 수정과, @emzero을 기반으로

    그리고 여기 내 버전은 레일 3.2에서 테스트 jQuery로 작업에 대한 수정과, @emzero을 기반으로

    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
    
    // 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
    });
    
            #flash-message
                - flash.each do |name, msg|
                    = content_tag :div, msg, :id => "flash_#{name}"
    
  3. ==============================

    3.이 작업은 JS 대응 필요

    이 작업은 JS 대응 필요

    당신이 RSJ을 사용하는 경우 :

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

    당신이 jQuery를 사용하는 경우 :

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

    4.나는 이런 식으로했다 ..

    나는 이런 식으로했다 ..

    제어 장치:

    전망:

    <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 %>");
    
  5. ==============================

    5.다른 사람의 위에 구축 -

    다른 사람의 위에 구축 -

    (우리는 브라우저에서 전체 플래시 객체를 재구성하는 우리를있게, JSON으로 전체 플래시 객체를 전달합니다.이 모든 플래시 메시지가 레일에 의해 생성되는 경우 여러 개의 플래시 메시지에 표시되어 있는지 확인하는 데 사용할 수 있습니다.)

    #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
    }
    
  6. ==============================

    6.현재 작업에서만 사용할 수 있습니다 아니라 다음에 : [주의], 당신이 필요로하는 무엇처럼 보인다는 flash.now입니다. 현재 문서에서 좀 걸릴 수 있습니다 : http://api.rubyonrails.com/classes/ActionController/Flash/FlashHash.html#M000327

    현재 작업에서만 사용할 수 있습니다 아니라 다음에 : [주의], 당신이 필요로하는 무엇처럼 보인다는 flash.now입니다. 현재 문서에서 좀 걸릴 수 있습니다 : http://api.rubyonrails.com/classes/ActionController/Flash/FlashHash.html#M000327

  7. ==============================

    7.이 같은 컨트롤러에서 메시지를 할당합니다 :

    이 같은 컨트롤러에서 메시지를 할당합니다 :

      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 %>
    
  8. ==============================

    8.gudleik 답변에 따라 :

    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
    

    그런 다음 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
       }
    });
    
  9. ==============================

    9.자동으로 인코딩 쿠키에 메시지를 플래시 겸손한 플래시이라는 보석이 있습니다. 플래시에 대한 클라이언트 측 검사에서 자바 스크립트와 당신이 원하는 방식으로 표시됩니다. 이것은 보통 및 아약스 요청에 원활하게 작동합니다.

    자동으로 인코딩 쿠키에 메시지를 플래시 겸손한 플래시이라는 보석이 있습니다. 플래시에 대한 클라이언트 측 검사에서 자바 스크립트와 당신이 원하는 방식으로 표시됩니다. 이것은 보통 및 아약스 요청에 원활하게 작동합니다.

  10. ==============================

    10.나는 플래시가 .blank [입력] 어떤 경우를 해결하기 위해 빅터 S '대답을 수정? 코멘트에 몇 사람에 의해 언급 한 바와 같이 작동하지 않았다.

    나는 플래시가 .blank [입력] 어떤 경우를 해결하기 위해 빅터 S '대답을 수정? 코멘트에 몇 사람에 의해 언급 한 바와 같이 작동하지 않았다.

    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
    
    });
    
  11. ==============================

    11.여기 내 버전 (배수 통지 및 특수 문자를 UTF-8 인코딩을 플래시 작업)한다 :

    여기 내 버전 (배수 통지 및 특수 문자를 UTF-8 인코딩을 플래시 작업)한다 :

    내부와 ApplicationController :

    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
    

    내 커피 스크립트 (트위터 부트 스트랩 버전) 내부 :

    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>")
    
  12. ==============================

    12.또 다른 방법은 / 업데이트 할 수 귀하의 아약스 요청하는 "OnFailure"핸들러의 메시지와 함께 "통지"사업부를 표시합니다. 그것은 당신에게 필요한 효과 이러한 플래시 메시지를 표시 할 수있는 기능을 제공합니다. 나는 이것을 사용

    또 다른 방법은 / 업데이트 할 수 귀하의 아약스 요청하는 "OnFailure"핸들러의 메시지와 함께 "통지"사업부를 표시합니다. 그것은 당신에게 필요한 효과 이러한 플래시 메시지를 표시 할 수있는 기능을 제공합니다. 나는 이것을 사용

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

    자바 스크립트에서

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

    HTH

  13. ==============================

    13.나는 사람이 제안 당신의 일부로서 응답 헤더에 플래시 메시지를 보낼 application_controller 몇 가지 동작을 포함하는 엔진을 구축 할 수 있습니다.

    나는 사람이 제안 당신의 일부로서 응답 헤더에 플래시 메시지를 보낼 application_controller 몇 가지 동작을 포함하는 엔진을 구축 할 수 있습니다.

    https://github.com/bonzofenix/flajax

  14. ==============================

    14.나는 page.reload_flash 기본을하고 생각할 수있는 유일한 개선 (page.keep_flash처럼 뭔가를 모든 RJS 파일에 넣어, 당신은 플래시를 다시로드하지 않으려면이 expicit 할 필요가 없습니다.

    나는 page.reload_flash 기본을하고 생각할 수있는 유일한 개선 (page.keep_flash처럼 뭔가를 모든 RJS 파일에 넣어, 당신은 플래시를 다시로드하지 않으려면이 expicit 할 필요가 없습니다.

    어디서부터 시작 해야할지하지만 몇 가지를 알고있는 것은 열심히하는 것이 그렇지 않은 확신 레일하지 않을 것입니다.

  15. ==============================

    15.경우에 당신은 컨트롤러에서 사용할 수 없습니다 AJAX 호출의 redirect_to를 사용하고 싶습니다. 오히려, 플래시 메시지가 명시 적으로 표시해야합니다 :

    경우에 당신은 컨트롤러에서 사용할 수 없습니다 AJAX 호출의 redirect_to를 사용하고 싶습니다. 오히려, 플래시 메시지가 명시 적으로 표시해야합니다 :

    your_controller에서 :

    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를 사용하는 경우 라인 ( '. 메시지') HTML ( "<% = J (렌더링 '레이아웃 / 메시지') %>") $가된다;

    HAML / ERB에 포함 된 위의 자바 스크립트가 AJAX를 사용하면 플래시 메시지를 표시하는 열쇠입니다. 다른 모든 구성 요소가 아닌 AJAX 호출을위한 동일하게 유지.

    당신은 your_ajax_method_in_the_controller.js.coffee 또는 일반의 .js를 사용할 수 있지만, 그 변수는 JS / 커피에 사용할 수 없습니다 레일. 내가 여기에 변수를 사용하지 않더라도 나는 일관된 코드베이스를 유지하기 위해 HAML에서 JS를 포장하는 것을 선호합니다.

    I 활용 트위터 부트 스트랩 따라서, 메시지를 스타일링을위한 $ ( ". 경고"). 경고 ( '가까운') 사라져 통지. 그리고 여기에 메시지 부분입니다 :

    레이아웃 / _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;
    }
    
  16. from https://stackoverflow.com/questions/366311/how-do-you-handle-rails-flash-with-ajax-requests by cc-by-sa and MIT license