Вопрос по ajax, ruby-on-rails, will-paginate – Как сделать две разбитые на страницы и настраиваемые коллекции в одном представлении?

8

В индексном представлении 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 %>

Как я могу передать locals в 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

Спасибо за любые идеи.

Не обязательно, но ясно, когда вы делаете этот вызов для рендеринга, вы должны сказать, какую коллекцию вы хотите отрендерить Frederick Cheung
когда вы говорите, что нумерация страниц не работает, что происходит? Frederick Cheung
ничего такого! У меня есть функция JavaScript, делающая запрос AJAX. Функция запускается (добавляет spinner.gif), но больше ничего не происходит. Вам нужен журнал? Эта проблема кажется мне странной. Все отлично работает с@user но разваливается, когда я пытаюсь пройти как местный. Есть ли причина, по которой will_paginate не будет принимать локальный? Andy Harvey
Спасибо, я попробовал это согласно ответу ниже. Но, возможно, я не совсем понимаю, как это реализовать. Чтобы передать местным жителям вescape_javascript(render("users/user")) мне понадобится два файла index.html.erb, верно? По одному на каждую коллекцию, которую мне нужно сделать? Andy Harvey
Почему вы не передаете какие-либо локальные данные, когда выполняете escape_javascript (render (& quot; users / user & quot;))? Frederick Cheung

Ваш Ответ

3   ответа
4
you need to make sure the controller knows which page link of which listing you press. we do this by passing a param to will_paginate page link generator. you need to make sure your js updates the correct html tag when refreshing the pagination of either listing. we do this by wrapping the pagination in a mood-dependent :) div tag. since we share the partial we need to make sure mood as well as correct collection is set in controller and passed to partial as local from index views (both html and js). finally make sure your ajax remote picks up after you redraw pagination (this is a bonus)

установить экземпляр контроллера в зависимости от параметра настроения запроса

note that this code also spares you some db calls, since if you just pagintae sad users you do not need to retrieve happy ones or all). I ommit @users for simplicity, its never used I suspect happy scope for sad users is only a typo

.

# 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. Также укажите настроение в запросе URL.

# 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 Пагинация и сортировка

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

Обратите внимание, что решение должно работать даже в том случае, если javascript не включен, и мы используем html. В этом случае оба раздела должны быть повторно отображены с учетом разных страниц.

MODIFIED CODE TO ALSO HANDLE GRACEFUL JS FALLBACK TO 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 })) %>
');

после этого будут сохранены счастливые страницы в параметре, если щелкнет печальная ссылка на страницу, и наоборот.

# 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>
на самом деле, поцарапатьGET http://path/to/app/users 500 (Internal Server Error), Это не связано. Andy Harvey
dagnammit! Это былreally расстраивающий вопрос. Я изменил синтаксис функции index.js.erb изescape_javascript(render("users/user", locals:... вescape_javascript(render :partial => "users/user", locals:.., Местные жители теперь работают как положено. Срыв! Andy Harvey
просто быстрый вопрос, чтобы проверить - коллекцию / массив можно установить как локальный? или местный ожидает строки / целые числа? Andy Harvey
и поцарапать местный = & gt; вопрос массива. Конечно может. Andy Harvey
спасибо Виктор, это отличный ответ. извиняюсь за медленный ответ - я тщательно изучал мою проблему, чтобы обнаружить любые глупые ошибки. к сожалению, это все еще не работает для меня. Если я установил это без использования местных жителей, все работает отлично. Как только у меня появились местные жители, ничего не работает (javascript запускается, но ajax-запрос не выполняется). глядя в мою консоль я вижуGET http://path/to/app/users 500 (Internal Server Error) с местными жителями, чего не бывает без местных жителей. Любая идея, почему добавление местных жителей может вызвать это? Andy Harvey
0

создайте в контроллере два разных метода для каждого списка, например, fill_list1 и fill_list2, которые не зависят от метода создания главной страницы, например, index

Каждый метод списка должен отображать частичное без макета, например

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

Главная страница должна вызывать частичные представления в первый раз.

когда вы нажимаете в paginate control, вы должны взломать click для вызова ajax следующий список элементов нумерации страниц

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

index.html.erb:

$(".ajaxable-users").html('
  <%= escape_javascript(render("users/user", locals: { users: @users })) %>
');
спасибо @gmile, к сожалению, это не улучшило ситуацию. Также я думаю, что это затруднило бы достижение того, на что я надеюсь - т.е. иметь два разбитых на страницы и настраиваемых списка на одной странице, каждый из которых отображал бы свою коллекцию. Andy Harvey

Похожие вопросы