【问题标题】:How to render two paginated and ajaxable collections in the same view?如何在同一个视图中呈现两个分页和 ajaxable 集合?
【发布时间】:2012-05-22 19:08:38
【问题描述】:

在 Rails 3.2 索引视图中,我正在渲染两个部分。

<%= render :partial => 'users/user', :locals => {:users => @happy_users} %>
<%= render :partial => 'users/user', :locals => {:users => @sad_users} %>

并在部分

<% users.each do |user| %>
  Show some fields
<% end %>
<%= will_paginate users %>

分页不起作用。

如果我更改 will_paginate 以获取实例变量,则分页有效(但集合错误)

<%= will_paginate @users %>

如何在调用部分时将本地变量传递给 will_paginate?

(我意识到我还需要通过 :param_name 才能让这与两个集合一起工作。现在我只是想让一个实例工作。)

部分通过 index.js.erb 渲染

$(".ajaxable-users").html('<%= escape_javascript(render("users/user")) %>');

控制器看起来像

def index
  @users = User.scoped.paginate(:page => params[:page], :per_page => 5)
  @happy_users = User.happy_scope.paginate(:page => params[:page], :per_page => 5)  
  @sad_users = User.happy_scope.paginate(:page => params[:page], :per_page => 5)  

  respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @users }
      format.json { render :json => @users }
      format.js
  end
end

感谢您的任何想法。

【问题讨论】:

  • 当你说分页不起作用时,会发生什么?
  • 没什么!我有一个发出 ajax 请求的 javascript 函数。该函数运行(它添加了一个 spinner.gif),但没有其他任何事情发生。你需要日志吗?这个问题对我来说似乎很奇怪。 @user 一切正常,但当我尝试以本地人身份通过时,一切都崩溃了。 will_paginate 有什么理由不接受本地人吗?
  • 为什么在执行 escape_javascript(render("users/user")) 时不传递任何本地人?
  • 谢谢,我按照下面 gmile 的回答进行了尝试。但也许我不完全理解如何实现这一点。在escape_javascript(render("users/user")) 中传递本地人需要我有两个 index.html.erb 文件,对吗?我需要渲染的每个集合一个?
  • 不一定,但很明显,当您调用渲染时,您必须说明要渲染哪个集合

标签: ruby-on-rails ajax will-paginate


【解决方案1】:
  1. 您需要确保控制器知道您按下了哪个列表的哪个页面链接。为此,我们将参数传递给 will_paginate 页面链接生成器。
  2. 在刷新任一列表的分页时,您需要确保您的 js 更新正确的 html 标签。我们通过将分页包装在一个与情绪相关的 :) div 标签中来做到这一点。
  3. 由于我们共享部分,我们需要确保在控制器中设置情绪和正确的集合,并从索引视图(html 和 js)作为本地传递给部分。
  4. 最后确保您的 ajax 遥控器在您重绘分页后能够启动(这是一个奖励)

所以,根据请求情绪参数设置控制器实例变量

  • 请注意,此代码还为您节省了一些数据库调用,因为如果您只是分页悲伤的用户,则不需要检索快乐的用户或全部)。
  • 为了简单起见,我省略了@users,它从未使用过
  • 我怀疑悲伤用户的快乐范围只是一个错字

.

# controller
def index
  @mood = params[:mood]
  @mood_users = @happy_users = User.happy_scope.paginate(:page => params[:page], :per_page => 5) if @mood.blank? || @mood == 'happy'
  @mood_users = @sad_users = User.happy_scope.paginate(:page => params[:page], :per_page => 5) if @mood.blank? || @mood == 'sad'

  respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @users }
      format.json { render :json => @users }
      format.js
  end
end

确保我们将正确的本地人分派给局部:

# index.html.erb
<%= render :partial => 'users/user', :locals => {:users => @happy_users, :mood => 'happy' } %>
<%= render :partial => 'users/user', :locals => {:users => @sad_users, :mood => 'sad' } %>

使部分情绪敏感,允许不同的 div 标签 ID。还要在请求网址中加上心情。

# users/user partial
<div id='<%= "#{mood || ''}users"%>'>
<% users.each do |user| %>
  Show some fields
<% end %>
<%= will_paginate users, :params => { :mood => mood } %>
</div>

此 js 允许根据按下的分页链接刷新不同 div 中的不同集合。

# index.js.erb
$("#<%= @mood %>users").html('
  <%= escape_javascript(render(partial: "users/user", locals: { users: @mood_users, mood: @mood })) %>
');

对于您需要的用于分页的不显眼的 ajax 链接。 Ruby - Rails 3 - AJAXinate Paginate and sorting

# in a generic js
$(document).ready(function () {
    $(".pagination").find("a").livequery(function () {
        $(this).attr("data-remote", true);
    });
});

请注意,即使未启用 javascript 并且我们使用 html,该解决方案也应该可以工作。在这种情况下,两个部分都应该重新显示以允许不同的页面。

修改后的代码也可以处理优雅的 JS 回退到 HTML

控制器

# controller
def index
  @mood = params[:mood]
  @happy_page = @mood == 'happy' ? params[:page] : params[:happy_page]
  @sad_page = @mood == 'sad' ? params[:page] : params[:sad_page]

  @mood_users = @happy_users = User.happy_scope.paginate(:page => @happy_page, :per_page => 5) if !request.xhr? || @mood == 'happy'
  @mood_users = @sad_users = User.happy_scope.paginate(:page => @sad_page, :per_page => 5) if !request.xhr? || @mood == 'sad'
  @mood_users = @users = User.scoped.paginate(:page => params[:page], :per_page => 5) if @mood.blank?

  respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @users }
      format.json { render :json => @users }
      format.js
  end
end

将新视图变量转发到部分本地

# index.html.erb
<%= render :partial => 'users/user', :locals => {:users => @happy_users, :mood => 'happy', :happy_page => @happy_page, :sad_page => @sad_page } %>
<%= render :partial => 'users/user', :locals => {:users => @sad_users, :mood => 'sad', :happy_page => @happy_page, :sad_page => @sad_page  } %>

我们只需要在这里传递这个,就不会得到部分未定义的方法。

# index.js.erb (fixed HTML syntax)
$("#<%= @mood %>users").html('
  <%= escape_javascript(render(partial: "users/user", locals: { users: @mood_users, mood: @mood, :happy_page => @happy_page, :sad_page => @sad_page })) %>
');

如果点击了悲伤的页面链接,这将在 param 中保留快乐的页面,反之亦然。

# users/user partial
<div id='<%= "#{mood || ''}users"%>'>
<% users.each do |user| %>
  Show some fields
<% end %>
<%= will_paginate users, :params => { :mood => mood, :happy_page => happy_page, :sad_page => sad_page  %>
</div>

【讨论】:

  • 感谢维克多,这是一个很好的答案。为缓慢的反应道歉 - 我一直在仔细研究我的问题,以发现任何愚蠢的错误。不幸的是,这仍然不适合我。如果我在不使用本地人的情况下进行设置,一切正常。一旦我有了本地人,就没有任何效果(javascript 运行,但 ajax 请求未完成)。在我的控制台中,我看到 GET http://path/to/app/users 500 (Internal Server Error) 有本地人,没有本地人就不存在。知道为什么添加本地人会导致这种情况吗?
  • 只是一个需要检查的快速问题 - 集合/数组可以设置为本地吗?还是本地期望字符串/整数?
  • 实际上,划掉GET http://path/to/app/users 500 (Internal Server Error)。那是无关的。
  • 该死!这是一个真的令人沮丧的问题。我将 index.js.erb 函数的语法从 escape_javascript(render("users/user", locals:... 修改为 escape_javascript(render :partial =&gt; "users/user", locals:..。当地人现在按预期工作。令人沮丧!
  • 即使我的问题是其他问题,我也会将您的答案标记为正确的。我认为这对未来的搜索者来说是一个很好的指南。为了完整起见,也许您想对我上面描述的render partial 问题添加一个小编辑?
【解决方案2】:

首先,在控制器中为每个列表创建两个不同的方法,例如fill_list1和fill_list2,创建主页的方法是独立的,例如索引

例如,每个列表方法都必须渲染一个没有布局的部分

render :partial=>'fill_list1', :layout => false

主页必须第一次调用局部视图。

当您点击分页控件时,您必须点击调用 ajax 下一个分页项列表

$('list1 a').live('click', function(event){
  event.preventDefault();
  $.ajax(
    {url:URLFORCALLMETHODLIST,
     success: function(content) {
                DIVLOCATIONLIST.html(content);
              },
     async:false,
    });
});

【讨论】:

    【解决方案3】:

    尝试在index.html.erb 中传递适当的本地人:

    $(".ajaxable-users").html('
      <%= escape_javascript(render("users/user", locals: { users: @users })) %>
    ');
    

    【讨论】:

    • 感谢@gmile,不幸的是这并没有改善。此外,我认为这会使实现我希望的目标变得困难 - 即在同一页面上有两个分页和 ajaxable 列表,每个列表显示不同的集合。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    • 2021-04-10
    • 1970-01-01
    • 1970-01-01
    • 2012-03-15
    • 2018-10-20
    相关资源
    最近更新 更多