【问题标题】:Rails 3 AJAX solution for updating tables?用于更新表的 Rails 3 AJAX 解决方案?
【发布时间】:2011-04-25 10:09:52
【问题描述】:

我知道这是一个热门话题,但我一直在寻找答案,但奇怪的是没有找到任何能够提供帮助的东西......

我有一个在表格中显示数据库条目的基本 Rails 3 应用程序。一个单独的应用程序将新条目发布到数据库中,我希望 Rails 应用程序轮询并刷新以显示新内容。现在,我有一段糟糕的 javascript 只是重新加载整个页面,它被证明是我的障碍。我有一个搜索栏和检查栏来删除多个项目,但是这些都在页面刷新时重置(再次,我知道这很糟糕而且非常糟糕)。

根据我的阅读,我认为我应该使用 AJAX 来轮询数据库并简单地呈现比显示的最新条目更新的数据库条目。如何精确执行这是另一回事...

我发现的大多数教程都已过时,而且我无法让遗留代码运行。我是 AJAX 和 Rails 的新手,如果有人有任何指导、建议、教程或个人批评 (:P) 可以为我指明正确的方向,我会很高兴。

谢谢!

编辑:我已将新条目拉入页面,但它们根本无法正确呈现。出于某种原因,它们没有作为条目添加到我的表中。这是我的代码,希望你们能够挑选出我错过的东西: * 注意 -> requests 实际上是我的数据库条目的名称。 Requests 是模型。

views/requests/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>

请求部分:views/requests/_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>

views/requests/index.js.erb

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

【问题讨论】:

  • 刚刚找到link。喜欢 Railscasts,我将通过它来看看它是如何进行的。

标签: ruby-on-rails ajax ruby-on-rails-3


【解决方案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 步:设置“成功”处理程序,以便当您的服务器返回零行或多行数据时,您可以在表中插入这些 TR-TD-/TD-/TR 行。

第 6 步:更新任何内部垃圾,例如数字或行计数器或您的 Javascript 正在跟踪的任何其他内容。

注意:您可能会发现其他人编写的插件可以很好地工作并为您省去麻烦,但您应该对这是如何完成的有一个基本的了解。

【讨论】:

  • DataTables 看起来非常棒,我一定会去看看。我一直在关注我为回答我的问题而发布的教程,实际上我正在很好地呈现新条目(它使用 jQuery,并且几乎完全按照您的步骤进行操作)。不幸的是,新显示的内容没有使用表格的 CSS 呈现?我可能错过了为什么会发生这种情况的任何明显原因?
  • 没有看到 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
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-06
    • 2011-09-03
    • 1970-01-01
    相关资源
    最近更新 更多