4

我在我的Rails 3应用程序中使用了jquery timeago plugin。我对我的帖子有一个评论部分#show view,它会每30秒自动刷新Railscasts#229 "Polling for Changes"中使用的AJAX。由jQuery加载的_comment部分包含使用timeago Rails帮助器方法创建具有正确时间格式的attr标记的注释的created_at时间。获取jQuery timeago插件来识别新加载的DOM元素

当提交注释并且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)) %>"); 

公共/ Java脚本/ 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轮询和timeago插件功能在其他任何地方都能正常工作,它只是在我发表评论时发表评论,并且该评论与我在另一个浏览器中运行的AJAX一起显示这个问题。 任何建议,资源或代码将使我的一周。感谢您阅读我的文章。

回答

13

您的代码在应用程序模板的脚本块中调用$("abbr.timeago").timeago();。这是在第一次加载页面时运行的,并且在匹配此时存在的元素时启用timeago功能。之后动态添加的任何匹配节点(例如您的AJAX部分)将执行而不是可获取timeago功能。

一个选项是在添加动态内容后再次调用$("abbr.timeago").timeago()。但是,添加新功能时可能难以跟踪并记住要做的事情,这就是为什么我使用livequery plugin代替的原因。包括的liveQuery脚本在你的页面,并用以下内容替换$("abbr.timeago").timeago();

$("abbr.timeago").livequery(function() { $(this).timeago(); }); 

这使得TIMEAGO任何匹配的节点,现在动态添加匹配的节点。

+0

它对我来说工作得很好,但它与动态内容一起使用时存在延迟的唯一问题,它显示了一秒钟后的实时时间,或者显示了timeago时的实时时间:(这在许多情况下显示不佳。丑陋的日期时间 – 2011-06-28 17:17:42

+0

你可以在你设置的CSS: .timeago { 显示:无 } 然后在的liveQuery功能只是代码$(本).show(); – 2013-03-18 12:02:40

+0

@AmrElgarhy的唯一方法是左右是默认显示一个奇特的日期。 – rybo111 2015-07-04 13:12:20

3

一旦load()完成了它的事情,ajaxComplete()被调用。我会建议创建一个名为ready_or_not()功能:

$(document).ready(function(){ 
    ready_or_not(); 
}); 

$(document).ajaxComplete(function(){ 
    ready_or_not(); 
}); 

function ready_or_not(){ 
    $(".timeago").timeago(); 
} 

可能有一定的代码,你只需要运行时文件已准备就绪,或者当阿贾克斯完成。但是对于这两个,把它放在ready_or_not()函数中。