3

will_paginate gem を使用して Ajax 呼び出しを実装しようとしていますが、このガイドhttp://ramblinglabs.com/blog/2011/11/rails-3-1-will_paginate-and-ajaxを見つけました。私がよく知らないcoffeescriptが含まれているので、誰かが別の解決策を持っている場合はアドバイスしてください..

私のコードは次のとおりです

私の見解

<div class="container">
 <div class="row">
  <div id="userRecipes">
   <%= render partial: 'userrecipes' %>
 </div>
</div><!--/row-->

私の部分 (ユーザーレシピ)

 <% @recipes.each do |r| %>
  <div class="span3">
   <div class="thumbnail">
    <%= image_tag r.avatar.url(:myrecipes) %>
   </div>
   <h4><%= link_to r.dish_name, r %></h4>
   <hr>
    <p><%= truncate r.description, :length => 90 %></p>
    <p><%= link_to "Edit Recipe", edit_recipe_path(r.id) %></p>
    <p><%= link_to "Delete Recipe", recipe_path(r.id), :confirm => "Are you sure?", :method => :delete %></p>
    <p><%= link_to "Add to favorites",  {:controller => 'favourites', :action => 'create', :recipe_id => r.id}, {:method => :post } %></p>
   </div><!--/span3-->
   <% end %>
   <%= will_paginate @recipes %>

更新された userrecipes.js.erb ファイル

$('#userRecipes').html('<%= escape_javascript(render partial: 'userrecipes') %>');
$.setAjaxPagination();

コーヒースクリプト

$ ->
$.setAjaxPagination = ->
$('.pagination a').click (event) ->
  event.preventDefault()
  loading = $ '<div id="loading" style="display: none;"><span><img src="/assets/loading.gif" alt="cargando..."/></span></div>'
  $('.other_images').prepend loading
  loading.fadeIn()
  $.ajax type: 'GET', url: $(@).attr('href'), dataType: 'script', success: (-> loading.fadeOut -> loading.remove())
  false

  $.setAjaxPagination()

次のアンカー タグをクリックして次の結果セットを表示すると、ページはそのまま残り、新しいコンテンツは表示されません

コンソールを使用してエラーがあるかどうかを確認すると、出力は次のようになります

GET http://localhost:3000/my_recipes?page=2&_=1355055997639

ここで何か不足していますか?または、私のuserrecipes.js.erbファイルに問題がありますか?他のAjaxの例では、パーシャルをレンダリングするときにescape_javascriptを使用しているのを見たからですか?

編集

コンソールで応答を調べている間、ロードされる新しいレシピがロードされていることも示されていますが、ビューでは何も起こっていません

任意のポインタをいただければ幸いです

ありがとう

4

5 に答える 5

11

より単純なアプローチを試してみませんか。次の内容で新しいヘルパー (例: app/helpers/will_paginate_helper.rb) を作成します。

module WillPaginateHelper
  class WillPaginateJSLinkRenderer < WillPaginate::ActionView::LinkRenderer
    def prepare(collection, options, template)
      options[:params] ||= {}
      options[:params]['_'] = nil
      super(collection, options, template)
    end

    protected
    def link(text, target, attributes = {})
      if target.is_a? Fixnum
        attributes[:rel] = rel_value(target)
        target = url(target)
      end

      @template.link_to(target, attributes.merge(remote: true)) do
        text.to_s.html_safe
      end
    end
  end

  def js_will_paginate(collection, options = {})
    will_paginate(collection, options.merge(:renderer => WillPaginateHelper::WillPaginateJSLinkRenderer))
  end
end

次に、ビューで ajax ページネーションに次のタグを使用します。

<%= js_will_paginate @recipes %>

ページネーション リンクには URL の既存のパラメーターが含まれることに注意してください。以下に示すように、これらを除外できます。これは標準のページネーション機能です。

<%= js_will_paginate @recipes, :params => { :my_excluded_param => nil } %>

問題が解決することを願っています。

説明:

Will_paginate を使用すると、独自のカスタム レンダラーを作成できます。WillPaginateJSLinkRenderer はそのようなカスタム レンダラーであり、このクラスはどこでも定義できます。ヘルパー モジュール内で定義する必要はありません。カスタム レンダラーは標準レンダラー (LinkRenderer) を拡張し、2 つのメソッドのみを再定義します。

will_paginate は、ページのレンダリング時に存在していたすべてのパラメーターを使用してページ URL を作成し、キャッシュ無効化パラメーターを再利用したくないため、prepare メソッドをオーバーライドしてキャッシュ無効化パラメーターを明示的に削除します。

link メソッドは元の LinkRenderer ソース コードからのコピペですが、remote:true でリンクを作成し、JS リクエストにします。

最後に、js_will_paginateメソッドは、通常の will_paginate ビュー ヘルパー メソッドを呼び出す標準のビュー ヘルパー メソッドですが、カスタム レンダラーをオプションに追加して、通常のレンダラーの代わりに使用されるようにします。

于 2012-12-20T15:21:52.977 に答える
3

誰かが Rails 4 ソリューションを探している場合に備えて。Pierre Pretorius からの回答が気に入りましたが、4.1.1 では link_to_function の「メソッドが定義されていません」という行で失敗しまし

@template.link_to_function(text.to_s.html_safe, ajax_call, attributes)

行を次のように置き換えました。

@template.link_to(text.to_s.html_safe, '#', attributes.merge(:onclick => "#{ajax_call} event.preventDefault();"))

誰かの役に立てば幸いです。

于 2014-06-28T10:53:31.360 に答える
2

js.erbでjavascriptをエスケープしていないので、問題があるはずです。

$('#userRecipes').html('<%= escape_javascript(render partial: 'userrecipes') %>');
$.setAjaxPagination();
于 2012-12-09T15:28:12.537 に答える
1

ピエール・プレトリウスの答えは素晴らしいですが、まだ明確になっていないことを機能させるために、もう少しやらなければなりませんでした。多分これは他の初心者に役立つでしょう。

そのヘルパーを作成し、js_will_paginateタグを使用することに加えて、私はこれを行いました:

ページ分割しようとしていたコンテンツをパーシャル (_recipes.html.erb上記の場合) に移動した後、次のshow.js.erbようなテキストを含むファイルも (パーシャルと同じビューで)作成しました。

$('#recipes').html('<%= escape_javascript(render partial: 'recipes') %>');

次に、js_will_paginate タグを下部のパーシャルにも移動する必要がありました (そのため、ページネーションを行ったり、次/前をクリックすると更新されます)。次に、js ファイルでターゲットにしている div id にレンダリング部分ヘルパーをラップする必要があったため、この例では次のようになります。

<div id="recipes">
  <%= render partial: "recipes" %> 
</div>

これは他の人にとっては非常に明確だったかもしれませんが、OP のどの手順を残す必要があり、どの手順が不要なのかわかりませんでした。これらの手順はうまくいきました。ヘルパーがそれを処理するか、coffeescript ファイルを持っているため、コントローラーに Respond_to js を追加する必要はありません。

于 2015-07-30T20:40:24.433 に答える
1

ajax_will_paginate は優れたメソッドですが、残念ながら、ページネーションの UI を台無しにしていました。柔軟性を高めるために、別の JavaScript メソッドを使用しました。そして、このメソッドを pageRender で呼び出します。

function checkForAjaxPaginate(controller,make_ajax){
    var href = "";
    $(".pagination").find("ul").each(function(){
        $(this).find("li").each(function(){
            $(this).find("a").each(function(){
                href = $(this).attr("href");
                if(href.indexOf(controller+".js") != -1){
                    if(make_ajax){
                        $(this).attr("data-remote","true");
                    }
                    else{
                        $(this).attr("href",href.replace(".js",""));
                    }
                }
            });
        });
    });
}

柔軟性を高めるために、「コントローラー」変数にアクション名を渡し、それを ajax に変換する場合は true を make_ajax に渡します。私がしているのは、href リンクが「.js」であるかどうかを確認することだけです。make_ajax が true の場合は、属性「data-remote=true」を追加します。これにより、ROR アプリでは ajax になります。make_ajax が真でない場合は、「.js」を削除するだけなので、コードが混乱することはありません。これが役立つことを願っています

于 2013-02-26T09:46:19.737 に答える