2012-11-29 13 views

Odpowiedz

26

Tworzenie nowego pomocnika (ex app/pomocników/will_paginate_helper.rb.) O następującej treści:

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 

Następnie w widoku użycia tego tagu na ajax paginacji:

<%= js_will_paginate @recipes %> 

Remember że łącza stronicowania będą zawierać istniejące parameny adresu URL, możesz je wykluczyć, jak pokazano poniżej.To jest standardowa funkcja stronicowania:

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

Mam nadzieję, że rozwiążesz problem.

Aktualizacja 1: Dodano wyjaśnienie, jak to działa dla original question, gdzie opublikowałem to rozwiązanie.

Aktualizacja 2: Zrobiłem to Szyny 4 kompatybilne ze zdalnymi: true linki i przemianowany metody pomocnika js_will_paginate.

+0

Widziałem twoją odpowiedź w kilku miejscach - i po wprowadzeniu twojego kodu kontroler jest zdecydowanie trafiony, a wyniki są wyciągane z bazy danych. Ale strona wcale się nie zmienia. czego mi brakuje? Dziennik serwera mówi "Rendered jobs/_jobstable.html.erb (80.7ms)", ale faktyczna strona na moim ekranie nie jest renderowana. – notaceo

+0

Przeglądarka wykonuje wywołanie ajax jquery (typu script), które oczekuje odpowiedzi JS, która zaktualizuje widok. Jednym ze sposobów odpowiedzi jest JS <% = "$ (" body "). Html ('# {escape_javascript (render' some_partial ')}');. Html_safe%> Ale możesz zmodyfikować kod nieco, aby zrobić cokolwiek chcieć. –

+1

Ten hack działa jak urok Railsów 3.x, ale nie jest już dostępny dla Rails 4.2. 'link_to_function' jest przestarzałe. Czy mógłbyś wprowadzić aktualizację? Z góry dziękuję. – BriceB

15

Hej, jeśli chcesz paginate produkty następnie spróbuj tego:

app/controllers/products_controller.rb

def index 
    @products = Product.paginate(page: params[:page], per_page: 10) 
end 

views/produkty/index.html.erb

<div class = "sort_paginate_ajax"><%= render 'products' %></div> 

odsłon /products/_products.html.erb

<% @products.each do |product| %> 
# your code 
<% end %> 
<%= will_paginate @products %> 

views/produkty/index.js.erb

$('.sort_paginate_ajax').html("<%= escape_javascript(render("products"))%>") 

aktywa/javascripts/application.js

$(function() { 
    $(".sort_paginate_ajax th a, .sort_paginate_ajax .pagination a").on("click", function(){ 
    $.getScript(this.href); 
    return false; 
    }); 
}); 

Więc najpierw wzywamy metodę paginate na Produktu dla wszystkich produktów, tutaj offset będzie ustawiona zgodnie z params[:page], a limit zostanie ustawiony za pomocą opcji per_page. Również wykonujemy renderowanie products częściowe, które będą renderowane za każdym razem, gdy otwierana jest inna strona.

W częściowego zaproszenia na @products które chcesz, a następnie will_paginate metoda jest stosowana na @products, ale również tworzy params[:page], który jest używany w kontrolerze.

Teraz w odpowiedzi na żądanie ajax treść renderowania div o klasie sort_paginate_ajax z częściowym, który stworzyliśmy.

Również do żądania żądania ajax, na skrypt przechwytywania obciążenia dokumentu wszystkich a znaczników w div.sort_paginate_ajax, i zwraca wartość false.

Teraz strona zostanie wywołana z żądania ajax

Mam nadzieję, że będzie Ci pomóc.

+2

miło, problem, który znalazłem jest to, że pierwsze kliknięcie na stronie działało dobrze, ale po przejściu do następnej strony wywołanie ajax nie było stosowane do linków i to został wywołany jako żądanie html, oznacza, że ​​gdy pierwsze wywołanie ajaxowe zostanie wykonane i częściowe zostanie zastąpione, to nie ma już wydarzenia na żywo dołączonego do linków paginacji, więc dodałem odpowiednie js do pliku js.erb, aby powiązać wydarzenie na żywo z linki, kiedy nowy fragment zostanie wyrenderowany i zadziałał świetnie. ! Uwaga, metoda na żywo jest przestarzała, począwszy od jQuery 1.7, więc musisz zastąpić ją .on() zamiast .live() – rmagnum2002

+0

@ rmagnum2002 kiedy powiesz, że dodałeś odpowiednie js do pliku js.erb możesz daj przykład, proszę im problem, w którym pierwszy następny link działa świetnie, ale następnie drugie żądanie generuje link w adresie URL na przykład /?_=1399023289230&page=3. Zmieniłem .live() na .on(), a także, dziękuję – Richlewis

+0

@Richlewis https://www.youtube.com/watch?v=UbtmSsjKn38 Użyłem tego kilka razy w moich projektach .. Can ' t naprawdę pamiętam, co było właściwe, o czym mówiłem. Może być związany ze zdarzeniami .on() i .live(). – rmagnum2002

3

Dodatkowa do poprzedniej odpowiedzi.

ciąg kodu:

$(".sort_paginate_ajax th a, .sort_paginate_ajax .pagination a").on("click", function(){ 

zastąpić sznurkiem:

$(".sort_paginate_ajax").on("click", ".pagination a", function(){ 

zdarzenie onclick stosowana tylko do elementów, które już istnieją. Tak więc, w przypadku nowych pojawiających się odsyłaczy, wymagane jest zdarzenie delegowania kliknięcia od rodzica ".sort_paginate_ajax" do elementu potomnego ".pagination a".

1

może po prostu użyć jQuery:

Kontroler:

def index 
    @posts = Post.paginate(:page => params[:page])  

    respond_to do |format| 
    format.html 
    format.js 
    end 
end 

Następnie w index.html.erb:

<div id="post-content", posts: @posts > 
    <%= j render 'post_content' %> 
</div> 

W częściowym '_post_content.html.erb':

<%= will_paginate @posts %> 
<% @posts.each do |post| %> 
    <p><%= post.content %></p> 
<% end %> 

pagination.js:

$(document).ready(function() { 
    $('.pagination > a').attr('data-remote', 'true'); 
}); 

index.js.erb:

$('#post-content').html("<%= j render 'post_content' %>") 

Upewnij się, aby dodać

$('.pagination > a').attr('data-remote', 'true'); 

ponownie w szablonie JS (index.js.erb), więc ustawia linki dane-zdalne ponownie, gdy działa Ajax.

0

Kontynuacja doskonałej odpowiedzi @ Pierre'a na stworzenie pomocnika, widziałem kilka pytań dotyczących aktualizacji widoków (problem, który początkowo miałem). @Pierre podąża za tym problemem, stwierdzając, że musisz utworzyć odpowiedź js. Oto co zrobiłem po utworzeniu pomocnika:

w moim show.html.erb

<div id="see-comments"> 
    <%= render @comments %> 
</div> 
<div id="pagination-comments"> 
    <%= js_will_paginate @comments %> 
</div> 

stworzyłem kolejny plik o nazwie show.js.erb (tak dwa formaty show)