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()函數中。