2011-02-17 28 views
2

我想使用jQuery在我的Rails 3应用程序中创建一个AJAX消息流。该应用程序显示帖子和帖子的回复。现在,它要求用户刷新浏览器更新:使用JQuery PeriodicUpdater和Rails的消息流

//in app/views/posts/_replies.html.erb 
<div class="replies"> 
    <% for reply in @replies %> 
     <div class="reply"> 
      <p><%= reply.body %></p> 
     </div> 
    <% end %> 
</div> 

我试图使用PeriodicalUpdater的jQuery的端口(https://github.com/RobertFischer/JQuery-PeriodicalUpdater/)到ajaxify的回复为不断更新的流。

基于Ryan Bates的Railscast(http://railscasts.com/episodes/136-jquery),这里是我有:

// in public/javascripts/application.js 
$(document).ready(function(){ 
$.PeriodicalUpdater('/replies', { 
    method: 'post', 
    data: ???, 
    minTimeout: 1000, 
    maxTimeout: 8000, 
    multiplier: 2, 
    type: 'json', 
    maxCalls: 0, 
    autoStop: 0 
}, function(data) { 
      ???? 
}); 
}); 

我是新来的JS和jQuery,所以我不清楚如何将当前帖子传递给服务器,也不知道如何让它自动呈现局部的replies。这里是我的代码的其余部分:

// in app/views/posts/show.js.erb 
$("#replies").append("<%= escape_javascript(render 'replies') %>"); 

// app/controllers/posts_controller.rb 
class PostsController < ApplicationController 
    def replies 
    @replies = Post.find(params[:id]).replies 
    respond_to do |format| 
     format.js 
    end 
    end 
end 

是否有某种方式来传递当前post到控制器的ID?甚至可能传递最后一个reply的ID,这样服务器将只发送新的回复?

另外,我是否必须手动追加PeriodicalUpdater的回调函数中的所有内容?或者是否有办法呈现show部分更新?

更新:我确实喜欢@Spencer下面的建议,将它改为首先有一个按钮,你推动做一个AJAX更新。

我无法通过该参数。我的实际代码查找基于一个独特的URL关键的东西,所以我只是有:

<input type="button" value="Refresh" onclick="getReplies('<%= @post.url_key %>');" /> 

然后在我的application.js文件:

function getReplies(url_key) { 
$.ajax({ 
    type: "POST", 
    contentType: "application/json; charset=utf-8", 
    dataType: "json", 
    url: "/replies", 
    data: { url_key: url_key }, 
    success: function(msg) { 
     $.each(msg.Replies, function(index, reply) { 
      $("#replies").prepend('<p>' + reply.body + '</p>') 
     }); 
    } 
}); 
} 

在我的控制,我有:

def replies 
    @post = Post.find_by_url_key(params[:url_key]) 

    respond_to do |format| 
    format.json { render :json => @post.replies } 
    end 
end 

我得到:

Processing by PostsController#replies as JSON 
Parameters: {"_json"=>"url_key=some-post"} 
←[1m←[35mPost Load (1.0ms)←[0m SELECT `posts`.* FROM `posts` WHERE (`posts`.`url_key` IS NULL) LIMIT 1 

所以看起来像参数不从params检索。

回答

1

我想我在这里看到几个问题。我建议分解这个问题,因为你说你是jQuery的新手。开始使用手动按钮通过AJAX检索最新帖子。处理完成后,转到定期更新程序。

我推荐的第二件事是研究人们使用jQuery的各种模板方法。也就是说,您应该让Ruby简单地返回一个JSON数据结构,然后您可以让jQuery使用这些数据结构并使用各种数据填充后期模板。

下面是我在其中一个网站上使用的模板方法示例。我从下面的静态HTML开始。

<table id="tblExpenses"><tbody> 
     <tr> 
      <th>Date</th> 
      <th>Title</th> 
      <th>Amount</th> 
      <th>Attachments</th> 
      <th colspan="2">&nbsp;</th> 
     </tr> 
     <tr class="expenseTemplate" style="display: none;"> 
      <td class="litDate"></td> 
      <td class="litTitle"></td> 
      <td class="litAmount"></td> 
      <td class="litAttachments">test</td> 
      <td><a class="lnkEdit" href="#">Edit</a></td> 
      <td><a class="lnkDelete" href="#">Delete</a></td> 
     </tr> 
    </tbody></table> 

然后,我对存储在数据库中的开销执行AJAX请求,并动态创建新行以插入到Expenses表中。

function showTaxYear(taxYearId) { 
    $.ajax({ 
     type: "GET", 
     contentType: "application/json; charset=utf-8", 
     dataType: "json", 
     url: "/Services/GetExpensesByTaxYearId", 
     data: { taxYearId: taxYearId }, 
     success: function(msg) { 
      $.each(msg.Expenses, function(index, expense) { 
       var row = $("#tblExpenses tr.expenseTemplate") 
        .clone() 
        .removeClass("expenseTemplate") 
        .show() 
        .addClass("expense") 
        .addClass("expenseid_" + expense.ID); 
       row.find("td.litDate").text(expense.Date); 
       row.find("td.litTitle").text(expense.Title); 
       row.find("td.litAmount").text(expense.Total); 
       row.find("a.lnkEdit").attr("data-id", expense.ID) 
            .unbind().click(function() { editExpense($(this)); }); 
       row.find("a.lnkDelete").attr("data-id", expense.ID) 
            .unbind().click(function() { deleteExpense($(this)); }); 
       if (expense.Attachment != "") 
        row.find("td.litAttachments").empty().append($("<a>View</a>").attr("href", expense.Attachment)); 
       else 
        row.find("td.litAttachments").empty(); 
       row.insertBefore("#tblExpenses tr.expenseTemplate"); 
      }); 
     } 
    }); 
} 

GetExpensesByTaxYearId返回JSON结果看起来像这样

{"Expenses":[{"ID":9,"Title":"Some expense","Description":"","Date":"02/02/2010","Amount":"$10.00","Tax":0.00,"Attachment":"","Total":"$10.00"}]} 

一旦你这样做,你实际上可以检查,看看是否你已经创建了你所能得到的一些数据从后一个元素Ruby通过做一个jQuery搜索。在我的示例中,例如,我可以检查类expenseid_<Identifier>中是否存在元素。如果是这样,我已经付出了这笔开支。

我知道这可能是很多咀嚼,但流AJAX内容有很多。让我知道我是否可以进一步澄清。

+0

@Spencer谢谢!我会尝试从更简单的版本开始。我很困惑,不过你怎样和在哪里用参数调用`showTaxYear`。 – 2011-02-17 00:53:29