我正在使用Rails 3应用程序中的jquery timeago plugin。我的帖子#show view中有一个评论部分,它使用Railscasts第229集"Polling for Changes"中使用的AJAX每30秒自动刷新一次。由jQuery加载的_comment部分包含注释的created_at时间,该时间使用timeago Rails帮助器方法以正确的时间格式创建attr标记。
当提交评论并且ajax加载评论时,jQuery timeago插件无法识别新的评论DOM元素。因此,不是评论显示为“大约一分钟前”的时间,而是显示“2010-11-21 23:08:36 UTC”。
我当然搜索了这个问题,并找到了关于使用.live(),. delegate()或livequery插件的建议。
评论/ index.js.erb的:
<% unless @comments.empty? %>
$("#comments").append("<%=raw escape_javascript(render(@comments)) %>").timeago();
<% end %>
评论/ show.js.erb:
$("#comments").append("<%=raw escape_javascript(render(@comments)) %>");
公共/ Javascript角/ application.js中:
$(function() {
if ($("#comments").length > 0) {
setTimeout(updateComments, 30000);
}
});
function updateComments () {
var post_id = $("#post").attr("data-id");
if ($("#comments").length > 0) {
var after = $(".comment:last-child").attr("data-time");
} else {
var after = "0";
}
$.getScript("/posts/" + post_id + "/comments?after=" + after)
setTimeout(updateComments, 30000);
}
助手/ application_help.rb:
module ApplicationHelper
def timeago(time, options = {})
options[:class] ||= "timeago"
content_tag(:abbr, time.to_s, options.merge(:title => time.getutc.iso8601)) if time
end
end
布局/ application.html.erb:
<!DOCTYPE html>
<html>
<head>
<%= stylesheet_link_tag 'style' %>
<%= javascript_include_tag :defaults %>
<%= javascript_include_tag 'jquery.timeago' %>
<%= csrf_meta_tag %>
</head>
<body>
<!-- ... -->
<script type="text/javascript">
$("abbr.timeago").timeago();
</script>
</body>
</html>
评论/ _comment.html.erb:
<div class="comment" data-time="<%= comment.created_at.to_i %>">
<%- if comment.commenter.empty? -%>
<%- else -%>
<span class="name">
<%- if comment.email.blank? -%>
<%= comment.commenter %>:
<%- else -%>
<a href="mailto:<%= comment.email %>"><%= comment.commenter %>:</a>
<%- end -%>
</span>
<%- end -%>
<%= simple_format @comment.body %>
<span class="time">
<%= timeago(comment.created_at) %>
</span>
</div>
帖/ show.html.erb:
<div id="post" data-id="<%= @post.id %>">
<%= link_to @post.title, @post %>
<%= simple_format @post.content %>
<% unless @post.comments.empty? %>
<div id="comments">
<%= render @post.comments %>
</div>
<% end %>
</div>
<div id="replyform">
<%= render "comments/form" %>
</div>
AJAX polling和timeago插件功能在其他任何地方都能正常工作,就在我发表评论的时候,这个评论出现在另一个浏览器的AJAX中,我遇到了这个问题。 任何建议,资源或代码都会成为我的一周。感谢您阅读我的帖子。
答案 0 :(得分:15)
您的代码在应用程序模板的脚本块中调用$("abbr.timeago").timeago();
。这是在第一次加载页面时运行,并在匹配当时存在的元素上启用timeago功能。以后动态添加的任何匹配节点 - 例如您的AJAX部分 - 执行不获取timeago功能。
一种选择是在添加动态内容后再次致电$("abbr.timeago").timeago()
。但是,在添加新功能时,很难跟踪和记住这样做,这就是我使用livequery plugin的原因。在页面中包含livequery脚本,并将$("abbr.timeago").timeago();
替换为以下内容:
$("abbr.timeago").livequery(function () { $(this).timeago(); });
这样可以在任何匹配的节点上启用timeago,现在和匹配节点动态添加。
答案 1 :(得分:4)
load()
完成后,ajaxComplete()
被调用。我建议创建一个名为ready_or_not()
的函数:
$(document).ready(function(){
ready_or_not();
});
$(document).ajaxComplete(function(){
ready_or_not();
});
function ready_or_not(){
$(".timeago").timeago();
}
您可能只想在文档准备好或Ajax完成时运行某些代码。但对于两者,请将其放在ready_or_not()
函数中。