2012-11-29 12 views

risposta

26

Creare un nuovo aiutante (ex app/aiutanti/will_paginate_helper.rb.) Con il seguente contenuto:

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 

Poi nel vostro uso vista questo tag per Ajax impaginazione:

<%= js_will_paginate @recipes %> 

Remember che i collegamenti di paginazione includeranno parametri esistenti dell'URL, è possibile escluderli come mostrato di seguito.Questo è standard impaginerà funzionalità:

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

Sperare che risolva il problema.

Aggiornamento 1: aggiunta una spiegazione di come funziona allo original question in cui ho pubblicato questa soluzione.

Update 2: Ho fatto che Rails 4 compatibile con remote: i veri legami e rinominato il metodo di supporto per js_will_paginate.

+0

Ho visto la tua risposta in alcuni punti e, dopo aver implementato il codice, il controller è sicuramente colpito e i risultati vengono estratti dal database. Ma la pagina non sta cambiando affatto. Cosa mi manca? Il log del server dice "Lavori resi/_jobstable.html.erb (80.7 ms)" ma la pagina effettiva sullo schermo non viene visualizzata. – notaceo

+0

Il browser sta effettuando una chiamata jquery ajax (di tipo script) che si aspetta una risposta JS che aggiornerà la visualizzazione. Un modo per rispondere è con JS <% = "$ ('body'). Html ('# {escape_javascript (render' some_partial ')}');". Html_safe%> Ma puoi modificare leggermente il codice per fare tutto ciò che vuoi volere. –

+1

Questo hack funziona come un fascino su Rails 3.x ma non è più disponibile per Rails 4.2. 'link_to_function' è deprecato. Potresti inserire l'aggiornamento? Grazie in anticipo. – BriceB

15

Hey, se si desidera impaginare i prodotti quindi provare questo:

app/controllers/products_controller.rb

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

Visto/prodotti/index.html.erb

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

vista /products/_products.html.erb

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

views/prodotti/index.js.erb

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

attività/javascript/application.js

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

Quindi, prima che stiamo chiamando il metodo paginate sul prodotto per tutti i prodotti, qui un offset sarà impostato in base a params[:page] e il limite verrà impostato dalle opzioni per_page. Inoltre stiamo rendendo il rendering parziale products che verrà visualizzato ogni volta che viene aperta un'altra pagina.

In chiamata parziale su @products che si desidera, e quindi will_paginate metodo viene applicato sulla @products, ma crea anche params[:page] che viene utilizzato in controller.

Ora in risposta a una richiesta di richiesta java il contenuto di div avente classe sort_paginate_ajax con il parziale che abbiamo creato.

Anche per richiedere una richiesta ajax, sullo script di caricamento del carico di tutti i tag a in div.sort_paginate_ajax e restituire false.

Ora pagine saranno chiamati con richiesta AJAX

Spero che questo avrebbe aiutato.

+2

bello, il problema che ho trovato è che il primo clic su una pagina ha funzionato bene, ma dopo il passaggio a una pagina successiva la chiamata ajax non applicava ai collegamenti ed è è stato chiamato come richiesta HTML, significa che quando viene effettuata la prima chiamata ajax e il partial viene sostituito non c'è più un evento live aggiunto ai collegamenti di paginazione, quindi ho aggiunto il js corretto al file js.erb per associare l'evento dal vivo a i link quando un nuovo partial sarà reso e ha funzionato alla grande. ! Nota, il metodo live è deprecato a partire da jQuery 1.7, quindi devi sostituirlo con .on() anziché .live() – rmagnum2002

+0

@ rmagnum2002 quando dici di aver aggiunto il file js corretto al file js.erb potresti fornire un esempio per favore, ho un problema in cui il primo collegamento successivo funziona alla grande ma poi la seconda richiesta genera un link nell'URL di /?_=1399023289230&page=3 per esempio. Ho cambiato anche .live() con .on(), grazie – Richlewis

+0

@Richlewis https://www.youtube.com/watch?v=UbtmSsjKn38 ho usato questo un paio di volte nei miei progetti .. Can ' Ricordo davvero qual era il vero js di cui stavo parlando. Potrebbe essere correlato agli eventi .on() e .live(). – rmagnum2002

3

In aggiunta alla risposta precedente.

stringa di codice:

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

sostituire con stringa:

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

evento The onclick applicato solo agli elementi già esistenti. Quindi, per i nuovi collegamenti, è necessario delegare l'evento click dal genitore ".sort_paginate_ajax" a childs ".pagination a".

1

Si potrebbe utilizzare JQuery:

Controller:

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

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

Poi nel index.html.erb:

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

In parziale '_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' %>") 

Assicurarsi di aggiungere il

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

di nuovo nel modello JS (index.js.erb), quindi imposta i link data-remote di nuovo quando viene eseguito l'Ajax.

0

Per seguire l'eccellente risposta di @ Pierre in merito alla creazione di un helper, ho visto alcune domande di follow-up relative all'aggiornamento delle visualizzazioni (un problema che avevo inizialmente). @Pierre fa seguito a questo problema affermando che è necessario creare una risposta js. Ecco quello che ho fatto dopo aver creato l'helper:

nel mio show.html.erb

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

ho creato un altro file chiamato show.js.erb (quindi due formati per lo spettacolo)

// to update comments  
$("#see-comments").html("<%= j render @comments %>"); 
// to update the pagination links 
$("#pagination-comments").html('<%= js_will_paginate @comments %>');