簡體   English   中英

使用will_paginate gem在rails 3.2.3中調用Ajax

[英]Ajax call in rails 3.2.3 with will_paginate gem

我試圖用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-->

我的部分(userrecipes)

 <% @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();

CoffeeScript的

$ ->
$.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?

編輯

在檢查控制台中的響應時,它還顯示正在加載要加載的新配方但視圖中沒有發生任何事情

任何指針贊賞

謝謝

為什么不嘗試更簡單的方法,使用以下內容創建一個新的幫助器(例如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)並僅重新定義兩種方法。

prepare方法被覆蓋以顯式刪除緩存buster參數,因為will_paginate使用呈現頁面時存在的所有參數創建頁面URL,並且我們不想重用cache buster參數。

link方法是來自原始LinkRenderer源代碼的復制粘貼,但是創建了一個與remote:true的鏈接,以使其成為JS resquest。

最后, js_will_paginate方法是一個標准的視圖助手方法,用於調用普通的will_paginate視圖助手方法,但是將自定義渲染器添加到選項中,以便使用它而不是普通的渲染器。

以防萬一有人在尋找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();"))

我希望它可以幫助某人。

你沒有逃避js.erb中的javascripts,這應該是問題所在。

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

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

為了更加靈活,您只需在“controller”變量中傳遞操作名稱,如果要將其轉換為ajax,則將true傳遞給make_ajax。 我所做的就是檢查href鏈接是否為“.js”,如果make_ajax為true,則添加attr“data-remote = true”,在我們的ROR應用程序中將其設為ajax。 如果make_ajax不是真的那么我只是刪除“.js”所以代碼不會亂。 我希望這有幫助

皮埃爾·普雷托里烏斯的答案很棒,但我必須多做一點才能讓它對我起作用,這一點尚不清楚。 也許這會對其他初學者有所幫助。

除了制作幫助器並使用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必須保留哪些步驟,哪些步驟是不必要的。 這些步驟對我有用。 您不需要在控制器中添加respond_to js,因為幫助程序負責處理或具有coffeescript文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM