2017-08-08 2 views
0

ajaxリクエスト後にユーザーにメッセージを表示するには、どのような方法(つまり、最も管理しやすい、DRY)が最適ですか?ajaxリクエストのDRYフラッシュメッセージを書き込む方法は?

明らかに、単一のJSコントローラアクションでこれを実現する最も簡単な方法は、関連するJS部分を使用することです。アプリはajaxedアクションが多数含まれている場合、例えば、

#create.js 
$('.flash-container').html('<p>SUCCESS!</p>'); 

はしかし、これはすぐに変更が必要な場合は、更新する多くのパーシャルを必要とし、unmaintainableになります。

私が現在使っているアプローチは以下の通りです。しかし、これはいつも非常に脆く、「ハッキリ」と思われます。私はRailsのコンベンションを見落とさなければなりませんか?

これは、最初にAjaxリクエストがページでトリガーされたときにThat page doesn't exist!を返します。すべての後続の要求は、ページがリロードされるまで、予期される結果を返します。何が起こっている?

#my_controller.rb 
def create 
    if @object.save 
    format.js { flash[:notice] = t('.notice') } 
    else 
    format.js { flash[:error] = t('.error') } 
    end 
end 
# application_controller.rb 
after_action :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 
end 
def flash_message 
    [:alert, :error, :notice, :success].each do |type| 
    return flash[type] unless flash[type].blank? 
    end 
    return nil 
end 

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

#flash.js.coffee 

$(document).ajaxComplete (event, request) -> 

    msg = request.getResponseHeader("X-Message") 
    type = request.getResponseHeader("X-Message-Type") 

    if msg 
    alert(msg) 

答えて

0

はなぜjs.erb部分に部分的にあなたのjsを変更し、あなたはそれではなく、ヘッダを通じて送信の標準JSに解析される前に、送信したいメッセージを埋め込むことではありませんか?あなたはまた、.js.erbファイルを持つことができ.html.erbファイル持つことができるのと同じ方法で

:保守性とドライ、それを維持するという点で

# create.js.erb 
<% if flash[:notice] %> 
$('.flash-container').html('<p><%= flash[:notice] %></p>'); 
<% end %> 

は、それは、単にダウンコード設計にあり作成するには、他の.js.erb parials内にレンダリングすることをjs.erb部分共有:

# some_controller.rb 
helper_method :handle_ajax_messages 

# create.js.erb 
$('.flash-container').html('<p><%= handle_ajax_messages %></p>'); 

#shared/_ajax_messages.js.erb 
<% if flash[:notice] %> 
$('.flash-container').html('<p><%= flash[:notice] %></p>'); 
<% end %> 
<% if flash[:error] %> 
$('.flash-container').html('<p><%= flash[:error] %></p>'); 
<% end %> 

# create.js.erb 
<%= render(partial: 'ajax_messages') %> 

はトップレベルのコントローラで共有helper_methodを作成

DDDにあるServiceObjectハンドラまたはファクトリを抽出して、#to_html#to_jsonなどのカスタムNoticeObjectまたは値オブジェクトを作成して、すべてのタイプの要求に対してDRYを維持する方法があります。いわゆる「Rails規則」から抜け出せば、コードをDRYにして保守するための他のオプションや方法は非常に多様です。

+0

この広範な回答をいただきありがとうございます。あなたの最初の提案は 'ajax_messages'をすべてのJS部分に手動で挿入する必要があります。しかし、「ajaxified messages」を、現在存在している、または将来追加される可能性のあるアクションのデフォルトにしたい場合、ヘッダーは最善の方法ですか?もしそうなら、なぜ私はこの奇妙な「そのページは存在しない!」という要求を最初に送信したのですか? –

+0

DDDが私が探しているものかもしれません。どのようにこのアプローチを実装するかをよりよく視覚化するのに役立つ基本的なレールの例/チュートリアルをお勧めしますか? –

+0

確かに、最初のセクションでは、jsファイルに埋め込みルビを使うことができ、あなたの望むどのような方法でもあなたのためにあなたの全体のルビコードベースを開くことができます。なぜあなたはページが存在しないのかわからないのですが、ヘッダーの面では実行可能なアプローチかもしれませんが、個人的には使用しません。ただし、DRY再利用可能なコードを簡単に作成できるので、DDDをお勧めします。これは、上記のように、翻訳可能なバリューオブジェクトを作成するように、ほとんどすべてのケースで簡単に適応でき、再利用できます。リンク: –

関連する問題