Will_paginate gem与Bootstrap内置面板冲突

时间:2016-01-23 19:48:59

标签: javascript jquery ruby-on-rails twitter-bootstrap

我的ruby-on-rails应用程序视图上有一个引导程序两个选项卡面板,其中每个选项卡显示不同的内容,并为每个选项卡生成一个分页。它适用于第一个选项卡。但是,当我在第二个选项卡上时,单击下一页将我发送回第一个面板。我明白问题是,当我点击下一页按钮时,页面会刷新。我还没有添加任何JS。有关如何解决这一冲突的任何建议吗?谢谢!

这是请求视图:

   <div class="panel with-nav-tabs panel-default" id = "requests">
      <div class="panel-head">
        <ul class="nav nav-tabs nav-justified" role="tablist">
          <li class="active"><a href="#pendingrequests" data-toggle="tab" aria-controls="filestab" role="tab" data-link = "/homestays/<%= params[:id] %>/pending_requests" data-activetab="pending">Pending Requests</a></li>
          <li><a href="#pastrequests" data-toggle="tab" aria-controls="filestab" role="tab" data-link = "/homestays/<%= params[:id] %>/past_requests" data-activetab="past">Past Requests</a></li>
        </ul>
      </div>
      <div class="panel-body">
        <div class="tab-content">
          <div class="tab-pane fade in active" id="pendingrequests">
            <%= render 'requests/pending_requests', :locals => {:pending_requests => @pending_requests} %>
          </div>
          <div class="tab-pane fade" id="pastrequests">
            <%= render 'requests/past_requests', :locals => {:past_requests => @past_requests} %>
          </div>
        </div>
      </div>
    </div>

这是部分: _pending_requests:

<% pending_requests.each do |request| %>
  <div class = "col-md-6" id = "request_panel">
    <div class="text-center">
      <div class="user-picture">
        <%= image_tag("find_user_rsz.png") %>
      </div>
      <div class = "name"> <%= request.name %> </div>
    </div>
  </div>
<% end %>
<%= will_paginate @pending_requests, param_name: 'pending' %>

_past_request:

<% past_requests.each do |request| %>
  <div class = "col-md-6" id = "request_panel">
    <div class="text-center">
      <div class="user-picture">
        <%= image_tag("find_user_rsz.png") %>
      </div>
      <div class = "name"> <%= request.name %> </div>
  </div>
<% end %>
<%= will_paginate @past_requests, param_name: 'past' %>

这是我的控制器动作:

def requests
end

def pending_requests
   @pending_requests = current_user.responses.paginate(:page => params[:pending], :per_page => 1)
end

def past_requests
   @past_requests = Student.all.paginate(:page => params[:past], :per_page => 1)
end

1 个答案:

答案 0 :(得分:0)

你必须更改will_paginate的参数。目前你有两页我猜。

  def get_files #loading files data with js on common_medias page
    @common_files = @conversation.messages.with_file.order(created_at: :desc).paginate(page: params[:files], per_page: 14)
    respond_to :js
  end

  def get_links #loading links data with js on common_medias page
    @message_links_pre = @conversation.messages.with_link.order(created_at: :desc).paginate(page: params[:links], per_page: 14)
    @message_links = @message_links_pre.map { |f| { link: f.link, created_at: f.created_at, user_id: f.user_id} }.flatten
    @common_links = formatting_links(@message_links)
    respond_to :js
  end

和部分中的html

<%= will_paginate @common_files, param_name: 'files'

<%= will_paginate @message_links_pre, param_name: 'links'

常见的html(基本的html,其中所有内容将由js加载; partials被添加到不同的tabpanels)

    <ul class="nav nav-tabs" role="tablist">
      <li role="presentation"><a href="#filestab" aria-controls="filestab" role="tab" data-toggle="tab" data-link = "<%= get_files_user_common_medias_path(@user)%>" data-activetab="file">Files</a></li>
      <li role="presentation"><a href="#linkstab" aria-controls="linkstab" role="tab" data-toggle="tab" data-link = "<%= get_links_user_common_medias_path(@user)%>" data-activetab="link">Links</a></li>
      <li role="presentation"><a href="#calendarstab" aria-controls="calendarstab" role="tab" data-toggle="tab" data-activetab="calendar">Calendar</a></li>
    </ul>
    <div class="tab-content">
      <div role="tabpanel" class="tab-pane" id="filestab">
        <%= render @common_files %> #for html version only
        <%= will_paginate @common_files, param_name: 'files'
      </div>
      <div role="tabpanel" class="tab-pane" id="linkstab">
        <%= render @common_links %> #for html version only
        <%= will_paginate @message_links_pre, param_name: 'links'  
      </div>
      <div role="tabpanel" class="tab-pane" id="calendarstab">
         #I haven't implemented calendar yet, so tab is empty at the moment
      </div>
    </div>

js(如果你在页面加载时渲染部分内容,则没有必要)

$(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
  var target = $(this).data("activetab");
  var href = $(this).data("link");
  $.ajax({
    type: "GET",
    url: href,
    data: {tab: target},
    dataType: "script"
  });
});

更新:

所以现在让我们坚持使用html版本,这意味着将加载所有数据。这是一个很好的解决方案,如果你有3个标签10个记录/页,那么你必须加载30个记录。这个解决方案搞砸了的地方是页面在变化。 3个选项卡然后html分页。您可以使用html初始加载,然后每个页面都可以无限滚动。 (https://www.youtube.com/watch?v=PQX2fgB6y10)。

现在是部分:

第一种方法:

requests.html.erb(或您所在的页面)

`<%= render 'folder/pending_requests'` and then the partial:

_pending_requests:

 <% @pending_requests.each do |pending_request| %>
   <%= pending_request.name %>
   .........
 <% end %>
 <%= will_paginate @pending_requests %> #this line can be in the partial or just under the render 'folder/.....; her it doesn't matter

第二种方法:

requests.html.erb(或您所在的页面)

 <%= render @pending_requests %>
 <%= will_paginate @pending_requests %> #must be here, can't be in the partial since the partial is just for 1 record

_pending_request.html.erb #name必须是呈现版本的单数版本,这仅指一条记录

 <%= pending_request.name %> #rails convention you don't need @
 ......

哪一个更好?如果你可以使用第二个,因为你将拥有可重复使用的部分,当你想使用js时它会派上用场。 (阅读它,它是值得的)

更新2:

html进近控制器(您希望在1个请求中加载所有数据,因此必须加载所需的所有数据。)

def requests
  @past_requests = .....
  @pending_requests = ......
end

js方法

def request
  #any other data you need on initial page load like
  @users = .....
  @profiles = ........
end

#when you make the js action request you have to loaf the data from these actions/routes, so reuqest will go to for instance /pending_requests and fetches the @pending_reuqests. 
def pending_requests
   @pending_requests = ......
   respond :js #read comment below
end

def past_requests
   @past_requests = ...... #read comment below
end

对js回复的评论

这是一个js响应,因此页面不会被重新加载,所以你留在/请求页面。你用js respoonse做什么取决于你。在rails中,您可以使用js.erb在服务器端组装它,然后将其附加到现有的dom $('#thistab').append(<%= j render @pending_requests %>) - &gt;这意味着您可以加载已经在rails侧创建的整个部分,因此浏览器将知道如何加载它。 Rails约定更喜欢这个,因为你可以重用部分,而不必在客户端组装html。如果你通过json发回,那么你必须准确告诉js文件如何处理数据,比如$('#thistab').append(<li>data.name</li><li>data.created_at</li>)这会让你编写一堆代码。基本上你必须在这里重写整个部分。如果您需要在客户端操作数据,或者您不需要像这种情况那样加载一堆html,Json是很好的方法。