2011-07-07 12 views
1

これは少し複雑な場合は申し訳ありません。私はできる限り最善の方法で説明しようとしますが、私が不明な場合は質問してください。私のRails 3 js.erbファイルでJS条件を使ってパーシャルをレンダリングすることはできますか?

私は、ステータスが自動更新されたページを必要とするRailsアプリケーションに取り組んでいます。このステータスページには、多くのステップがある試行回数が多いリクエストがあります。このページを合理的に最新の状態に保つために、JQueryを使用して5秒ごとにサーバーをポーリングしています。

これで、indexアクションを介してindex.js.erbファイルが表示されます。このファイルは現在、画面に表示されている内容に基づいて、どの部分を再レンダリングする必要があるかを判断するために設定されています。私は、リクエスト/試行/ステップがまだ更新されているかを知るために依然としてアクティブかどうかを判断するために、現在画面上にあるものを使用します。データベースがアイテムを非アクティブに更新し、オンスクリーンのアクティブなアイテムが新しい非アクティブなステータスを示すように更新されないようにするため、データベース内のアイテムを使用するのではなく、これを選択しました....しかし、もっと良い方法がありますこの。

今私の主な問題です。 、どんな条件、スクリプトの中で述べられていないすべてのパーシャルを評価し

if (some statement) {<%= escape_javascript(render :partial=>"my_partial") %>}

:私のERBファイルでは、私はたくさんのを持っています。これはレンダリング時間を指数関数的に増加させ、私たちのサーバーで大きな打撃を受けているようです。

現在画面に表示されているものに基づいて部分的にレンダリングする方法はありますか?

この試練にはより良いアプローチがありますか?私はダイナミックに更新されたステータスページが全面にあることを知っていますが、正しい方向に私を導く良い例を見つけることができませんでした。

また、ここでは実際のコードの一部を抜粋して、わたしが行っていることのより良い例を提供しています。私はかなり複雑なjavascriptに新しいので、私は何かを完全に種類がある場合私に知らせてください。

<%attempt.steps.each do |step| %> 
     /* If a status for this step already exists on the page, only update portions of it, otherwise append the step status to the page */  
     if (document.getElementById("step-status-<%= step.id %>")) { 
      $("#step-status-<%= step.id %>").html('<%= escape_javascript(render :partial=>'step_status', :locals=>{:step=>step}) %>'); 
     <% if step.log.present? #log will be present once step is complete %> 
      /* If the log isn't displayed on the page, add the partial to display it. This is supposed to allow for this partial to only be rendered once and not refreshed*/ 
      if ($("#step-<%= step.id %>-log pre").is(":empty")) { 
       $("#step-<%= step.id %>-log").html('<%= escape_javascript(render :partial=>'log_details', :locals=>{:step=>step}) %>'); 
       $("#step-<%= step.id %>-log-button").html('<%= escape_javascript(link_to("View Log", "#", :id=>"step-#{step.id}")) %>'); 
      } 
     <% end %> 
     } else { 
      $("#step-details-list-<%= attempt.id %>").append('<%= escape_javascript(render :partial=>"step", :locals=>{:step=>step}) %>'); 
     } 
    <% end %> 

ありがとうございました。トリッシュ

答えて

0

は、クライアント側に「last_updated_at」の概念を導入することを検討してください。お使いのコントローラで

def index 
    # Lets pretend the earliest you're interested in is 1 day ago 
    updated_since = params[:last_updated_at].try(:to_time) || 1.day.ago 

    # For ease, i'm doing the query here; this query may be more appropriate as a scope in the model 
    @steps = Steps.where(["updated_at > ?", updated_since]) 
end 

あなたindex.js.erbビューで:

<% @steps.each do |step| %> 
    var step_html = '<%= escape_javascript(render :partial=>'log_details', :locals=>{:step=>step}) %>'; 
    var step_ele = $('#step-<%= step.id %>')[0]; 
    if (step_ele) { 
    // Step was already in the page; just replace it 
    step_ele.html(step_html); 
    } 
    else { 
    // Step isn't on the page yet; append it to its container 
    $('#step-container').append(step_html); 
    } 
<% end %> 
window.last_updated_at = "<%= Time.now.to_s %>"; 

リクエストのためにこれを行うと、同様のモデルを試みます。

更新コードでlast_updated_atクエリ文字列を更新URLに追加すると、'http://stats.example.com/index.js?last_updated_at=' + window.last_updated_atのようになります。

脇に:あなたのモデルの名前を付けてください。リクエストクラスがすでにレールにあり、競合する可能性があります。

関連する問題