admin管理员组

文章数量:1433161

I have a long block of ments on a view of model Page. Instead of showing all the ments on page load, I'm trying to create a "view more" button that shows the next ten ments. The button sends an ajax request to the controller, which then renders this block using jquery:

_view_more.html.erb

<% ments.each_with_index do |ment, index|%>
  <% if (( index > @start_number) && (index < @end_number) ) %>
  <%= ment.text %>
<% end %>

Let's say I always want to show the next 10 ments. I would just set @start_number = @start_number + 10 and @end_number = @end_number + 10 in the controller, but instance variables get reset, so @start_number would be nil. How can I set a variable that increases by 10 upon every ajax request?

"view more" button

<%= link_to "view more", view_more_page_path, remote: true %>

pages_controller.rb

def view_more
  @page = Page.find(params[:id])
  respond_to do |format|
    format.html { redirect_to root_path }
    format.js
  end
end

view_more

$("#ments-body").append("<%= escape_javascript(render 'view_more') %>");

I have a long block of ments on a view of model Page. Instead of showing all the ments on page load, I'm trying to create a "view more" button that shows the next ten ments. The button sends an ajax request to the controller, which then renders this block using jquery:

_view_more.html.erb

<% ments.each_with_index do |ment, index|%>
  <% if (( index > @start_number) && (index < @end_number) ) %>
  <%= ment.text %>
<% end %>

Let's say I always want to show the next 10 ments. I would just set @start_number = @start_number + 10 and @end_number = @end_number + 10 in the controller, but instance variables get reset, so @start_number would be nil. How can I set a variable that increases by 10 upon every ajax request?

"view more" button

<%= link_to "view more", view_more_page_path, remote: true %>

pages_controller.rb

def view_more
  @page = Page.find(params[:id])
  respond_to do |format|
    format.html { redirect_to root_path }
    format.js
  end
end

view_more

$("#ments-body").append("<%= escape_javascript(render 'view_more') %>");
Share Improve this question asked Feb 15, 2015 at 19:03 Joe MoranoJoe Morano 1,89510 gold badges59 silver badges124 bronze badges 2
  • I understand that this doesn't answer your question, but are you sure you don't want to just keep track on the client side and send the start and (if necessary) end indexes with the ajax requests? – JMM Commented Feb 26, 2015 at 16:14
  • @JMM I hadn't considered it. How could I do that? – Joe Morano Commented Feb 26, 2015 at 16:42
Add a ment  | 

4 Answers 4

Reset to default 4

I will use haml and coffee-script

When rendering ments you put an html5 data attribute with the id of the ment:

#view where to render ments
%div#ments-wrapper{:"data-pageid" => @page.id}
  =render @ments
=link_to "View more", "#", id: "view-more-link"

The ment partial

#ments/_ment.html.haml
%p.single-ment{:"data-mentid" => ment.id}
  =ment.body

application.coffee

$ ->
  $("#view-more-link").on 'click', ->
    last_ment_id = $("#ments-wrapper .single-ment").last().data('mentid')
    page_id = $("#ments-wrapper").data("pageid")
    $.ajax
      url: "/ments/view_more"
      dataType: "script"
      data:
        last_ment_id: last_ment_id
        page_id: page_id

ments_controller

def view_more
  @page = Page.find(params[:pageid])
  if params[:last_ment_id]
    @ments = @page.ments.where("ments.id > ?", params[:last_ment_id]).limit(10)
  end
  respond_to do |format|
    format.js
  end
end

ments/view_more.js.erb

$("#ments-wrapper").append("<%= escape_javascript(render @ments) %>");

Note: I don't how your routes were set up so I put the page.id as a data-attribute as well

I would use already implemented pagination gems kaminari or will_paginate. I'll create this example using will_paginate.

First of all, it's important to say that your approach is incorrect, because it loads all ments every view_more request. If you want to show 10 ments, makes sense select only they from database, right? The pagination gem will do it for you!

Let's to the code:

"view more" button

<%= link_to "view more", view_more_page_path, remote: true, id: 'view-more-btn' %>

pages_controller.rb

def view_more
  @ments = Page.find(params[:id]).ments.paginate(page: params[:page], per_page: 10)
  respond_to do |format|
    format.html { redirect_to root_path }
    format.js
  end
end

_view_more.html.erb

<% @ments.each do |ment| %>
  <%= ment.text %>
<% end %>

view_more.js.erb

$("#ments-wrapper").append("<%= escape_javascript(render 'view_more') %>");
# We need to update the 'view more' link with the next page number
$('#view-more-btn').attr('href', '<%= view_more_page_path((params[:page] || 0) + 1) %>')

is it not good to update an hidden variable before making ajax call with the count..?

var currentVal = parseInt($("[type=hidden]").val());
$("[type=hidden]").val( currentVal + 1 );

add the hidden field right at the begining of the ments section with default value as "0"

<input type="hidden" name="hiddenId" id="hiddenId" value="0">

Hope it will help

If you want a quick and dirty approach, you could save start_number and end_number inside a cookie.

But keeping track of what needs to be rendered next on client side would be a right thing to do.

本文标签: javascriptHow can I update an instance variable with each ajax requestStack Overflow