Решение Rails 3 AJAX для обновления таблиц?

#ruby-on-rails #ajax #ruby-on-rails-3

#ruby-on-rails #ajax #ruby-on-rails-3

Вопрос:

Я знаю, что это популярная тема, но я довольно долго искал, пытаясь найти ответ, и, как ни странно, не нашел ничего, что могло бы помочь…

У меня есть базовое приложение Rails 3, отображающее записи базы данных в таблице. Отдельное приложение публикует новые записи в базе данных, и я бы хотел, чтобы приложение Rails проводило опрос и обновлялось для отображения нового содержимого. Прямо сейчас у меня ужасная часть javascript, которая просто перезагружает всю страницу и оказывается моим препятствием. У меня есть панель поиска и флажки для удаления нескольких элементов, но они оба сбрасываются при обновлении страницы (опять же, я знаю, что это ужасно и ужасно сломано).

Из того, что я прочитал, я понял, что я должен использовать AJAX для опроса базы данных и просто отображать записи базы данных, которые новее, чем самая новая отображаемая запись. Как точно выполнить это — другая история…

Большинство найденных мной руководств устарели, и я не смог запустить устаревший код. Я новичок как в AJAX, так и в Rails, и я был бы рад, если у кого-нибудь есть какие-либо рекомендации, туториалы или личная критика (: P), которые могут указать мне правильное направление.

Спасибо!

РЕДАКТИРОВАТЬ: у меня есть новые записи, которые загружаются на страницу, но они вообще не отображаются корректно. По какой-то причине они не добавляются в качестве записей в мою таблицу. Вот мой код, надеюсь, вы, ребята, сможете выбрать что-то, что я пропустил: * Примечание -> запросы на самом деле являются именем записей моей базы данных. Запросы — это модель.

просмотры / запросы /index.html.erb

     <table class="center">
<div id="requests">
 <tr>
    <th><%= sortable "Patient_Name", "Patient Name" %></th>
    <th><%= sortable "Room_Number", "Room Number" %></th>
    <th><%= sortable "Request" %></th>
    <th><%= sortable "Urgency" %></th>
    <th><%= sortable "count", "Request Count" %></th>
    <th><%= sortable "created_at", "Created At" %></th>
    <th></th>
  </tr>
<%= render @requests %>
</div>
</table>
  

Частичный запрос: просмотры / запросы /_request.html.erb

  <div class="request" data-time="<%= request.created_at.to_i %>">
    <tr>
        <td><%= request.Patient_Name %></td>
        <td><%= request.Room_Number %></td>
        <td><%= request.Request %></td>
        <td><%= request.Urgency %></td>
        <td><%= request.count %></td>
        <td><%= request.created_at.getlocal.strftime("%r on %D") %></td>
        <td><%= link_to 'Remove', request, :confirm => 'Are you sure?', :method => :delete %></td>
    </tr>
</div>
  

просмотры / запросы /index.js.erb

 $('#requests').append("<%=raw escape_javascript(render(@requests))%>");
  

Комментарии:

1. Только что нашел ссылку . Мне нравятся Railscasts, я собираюсь просмотреть их и посмотреть, как все получится.

Ответ №1:

Как это?

http://www.datatables.net/

здесь есть еще целый набор:

http://plugins .jquery.com/plugin-tags/ajax-table

Иногда лучше использовать то, что есть, чем создавать новое.

Но, отвечая на ваш вопрос, это зависит от того, управляете ли вы DOM самостоятельно или позволяете Prototype, jQuery, MooTools или чему-то еще выполнять тяжелую работу. Идея состоит в том, чтобы установить таймер в вашем Javascript, и когда таймер срабатывает, запрашивать обновления у сервера. Сервер — ваше приложение Rails — упакует все, что изменилось, и отправит его обратно.

Шаг 1: Определитесь с фреймворком. Я использую jQuery, но подойдет большинство.

Шаг 2: Определите формат данных. Я использую JSON, но подойдет XML.

Шаг 3: Настройте цикл таймера. Это включает в себя использование settimer () и сброс его после каждого наблюдения.

Шаг 4: В обработчике, который выполняется при срабатывании таймера, упакуйте временную метку «последний просмотренный» и отправьте запрос Ajax. То, как вы это делаете, варьируется от фреймворка к фреймворку — или, если вы кодируете прямо в DOM, от браузера к браузеру.

Шаг 5: Настройте обработчик «success», чтобы, когда ваш сервер возвращает ноль или более строк данных, вы могли вставить эти строки TR-TD- / TD-/ TR в свою таблицу.

Шаг 6: Обновите любой внутренний мусор, такой как счетчики чисел или строк, или что-либо еще, что отслеживает ваш Javascript.

Примечание: Вы можете обнаружить, что есть плагины, написанные другими людьми, которые будут отлично работать и избавят вас от проблем, но вы должны иметь базовое представление о том, как это делается.

Комментарии:

1. DataTables выглядит абсолютно фантастически, я обязательно это проверю. Я следовал руководству, которое я опубликовал в ответ на мой вопрос, и я на самом деле хорошо визуализирую новые записи (он использует jQuery и почти идентично следует вашим шагам). К сожалению, вновь отображаемое содержимое не отображается с помощью CSS таблицы? Какая-либо очевидная причина, по которой это может происходить, которую я, возможно, пропустил?

2. Трудно сказать, не видя CSS и ответа Ajax. Таблицы сложны, потому что браузеры должны действительно понимать все это, чтобы правильно разместить это на странице. Я бы рекомендовал просмотреть стили и вычисляемые стили в Firebug и посмотреть, что это показывает.

Ответ №2:

Сначала создайте конечную точку rails, которая может получать новые записи:

 # config/routes.rb
match '/records/new_since/:time', :to => 'records#new_since'

# app/controllers/records_controller.rb
class RecordsController < ApplicationController
  def new_since 
    @records = Record.where('created_at > ?', Time.parse(params[:time]))
    respond_to do |format|
      format.json do
       @records[:time] = Time.now.to_s(:db)
       render :json => @records.to_json
      end
    end
  end
end
  

Затем немного javascript на стороне клиента (прототип здесь):

 setInterval(
  function(){
    new Ajax.Request('/records/new_since/'   $('time')   '.json', {
      method: 'get',
      onSuccess: function(transport){
        var records = transport.response.responseJSON;
        // insert the last checked time into <div id='time'></div>
        $('time').innerHTML = records.time;
        // loop over response JSON and do what you want with the data
        records.each(function(record){
          $$('table#records').insert({
            bottom: '<tr><td>' record.attribute '</td></tr>';
          });
        });
      }
    });
  },
  30000
);
  

В качестве альтернативы, вместо отправки json, вы можете отобразить шаблон всех новых строк таблицы и просто добавить его тоже. Менее гибкое, но немного проще, если вы просто хотите добавить ответы внизу:

 def new_since
  @records = Record.where('created_at > ?', Time.parse(params[:time]))
  respond_to do |format|
    format.json {} # renders json template
  end
end

# app/views/records/new_since.html.json.erb
<% records.each do |record| %>
  <tr><td><%= record.attribute %></td></tr>
<% end %>

setInterval(
  function(){
    new Ajax.Request('/records/new_since/'   $('time')   '.json', {
      method: 'get',
      onSuccess: function(transport){
        var record_rowss = transport.response.responseText;
        $('time').innerHTML = records.time;
        $$('table#records').insert({bottom: record_rows});
      }
    });
  },
  30000
);