【问题标题】:Will_paginate gem conflicts with Bootstrap built in panelWill_paginate gem 与 Bootstrap 内置面板冲突
【发布时间】:2016-01-23 19:48:59
【问题描述】:

我的 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

【问题讨论】:

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


    【解决方案1】:

    您必须更改 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'
    

    common html(所有内容都将由 js 加载的基本 html;部分添加到不同的选项卡面板)

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

    【讨论】:

    • 谢谢!我刚刚将我的原始控制器操作添加到我的问题中。这就是我更改控制器操作的方式:def requests @pending_requests = User1.all.paginate(:page =&gt; params[:pending], :per_page =&gt; 1) @past_requests = User2.all.paginate(:page =&gt; params[:past], :per_page =&gt; 1) end 我是否正确理解您的答案?如果是这样,它似乎不起作用。
    • 你在视图中添加了param_name吗?
    • 西拉德·马扎尔,我做到了。它没有用。我只是把它们分成两页。为了解决这个问题,我假设我必须覆盖 gem 中的某些内容。我只是觉得不值得花太多时间在这上面。除非你有其他办法解决问题?
    • 这很奇怪。它对我来说很好。可能是因为您在同一操作中使用了 2 个分页。您不必分成 2 页。只需创建 2 个不同的操作。更新了我的答案。如您所见, data-link 属性告诉您激活了哪个操作。
    • 这样,每个选项卡的信息只有在激活时才被加载?我是否需要为此添加 ajax 代码,因为我假设我不能在一页内同时点击两个操作。
    猜你喜欢
    • 1970-01-01
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 2017-12-06
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 2015-04-01
    相关资源
    最近更新 更多