web-dev-qa-db-ja.com

railsで部分ページを非同期でロードする方法

Ruby on Rails/jquery app)を作成する際、ページの生成に時間がかかる部分があります。

ほとんどのページがすぐに読み込まれるようにページの読み込み方法を変更し、時間のかかる部分が非同期で読み込まれるようにプレースホルダーを予約し、完了時にajax/jqueryを使用してページに挿入します。

私が今持っているもの(簡略化):

app/views/sample/show.html.erb:

<div id="theResult">
    <%= render :partial => 'calculate', :object => @org) %>
</div>

パーシャルは、@ orgの一部を使用してコンテンツを生成します(別の外部RESTサービスにヒット)。

app/views/sample/_calculate.html.erb

<%
    # code to take org and turn it into content
%>
<!--...html to display results here -->

私のパーシャルはロジックが多すぎると思われるため、これはおそらく適切なMVCアーキテクチャルールに違反していることに気づき、それもクリーンアップしたいと思います...

だから私は2つの質問を1つに持っていると思います:(1)これをどのように機能させるか、そして(2)これをクリーンアップしてRuby/Rails/mvcの良い習慣に従うにはどうすればいいですか?

39
Krease

最初に、メインの応答に空のプレースホルダーdivを配置します

<div id="pink-dancing-elephants"></div>

ページに小さなjQueryを追加します

$.ajax({
    url: "/elephants/dancing",
    cache: false,
    success: function(html){
      $("#pink-dancing-elephants").append(html);
    }
});

/ elephants/dancing/pinkに応答して、divを埋めるHTMLのblobを返すアクションを実行します。 AJAXリクエストによって呼び出されるアクションでは、:layout => falseでレンダリングして、返されたHTMLのblobにフレーム全体が含まれないようにする必要があります。

# elephants_controller.rb
def dancing
  @elephants = #whatever
  render :layout => false
end

これにより、テンプレートがviews/elephants/dancing.html.erbにレンダリングされます。

67
cailinanne

@cailinanneに比べて、これを行う簡単な方法があります。

彼女の同じ例を使用しますが、私はこのテクニックを使用してdivを更新する傾向があるため、私のdivは最初にそのパーシャルを持ちます。

<div id="pink-dancing-elephants">
   <%= render "elephants/dancing", elephant: some_thing  %>
</div>

ただし、jQueryのloadメソッドを使用します。

$("#pink-dancing-elephants").load("/elephants/dancing");

これにより、部分全体が返されます。必ずlayout:falseを使用し、オプションでparamsを設定してください。私はこのような部分を使用する傾向があります

# elephants_controller.rb
def dancing
  render "elephants/_dancing", 
         locals: { elephant: some_thing },
         layout: false
end

これにより、テンプレートがviews/elephants/_dancing.html.erbにレンダリングされます。

コントローラメソッドの部分的な名前の下線と、ビューでrenderを呼び出すときにそれを使用しない方法に注意してください。

10
justingordon