4

私はRails 3アプリケーションでjquery timeago pluginを使用しています。 Railscasts episode#229 "Polling for Changes"で使用されているAJAXで30秒ごとに自動的に更新される、私の投稿#show viewのコメントセクションがあります。 jQueryによってロードされる_comment部分には、timeago Railsヘルパーメソッドを使用して正しい時刻形式のattrタグを作成するコメントのcreated_at時刻が含まれます。jQueryの取得時に、新しく読み込まれたDOM要素を認識するためのプラグイン

コメントが送信され、ajaxがコメントを読み込むと、新しいコメントDOM要素がjQueryタイムアゴプラグインによって認識されません。したがって、コメントの時間が「約1分前」と表示される代わりに、「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のポーリングとタイムアゴプラグインの機能は他の場所でもうまく動作します。私がコメントをしたときのことです。そのコメントは、実行している別のブラウザのAJAXで表示されますこの問題に。 すべての提案、リソース、またはコードが私の週を作るでしょう。私の記事を読んでくれてありがとう。

答えて

13

コードでは、アプリケーションテンプレート内のスクリプトブロック内で$("abbr.timeago").timeago();が呼び出されます。これは、ページが初めてロードされるときに実行され、その時点で存在する一致する要素のタイムアゴ機能を有効にします。後で動的に追加される一致するノード - たとえば、AJAXの部分 - はではなく、の機能を取得します。

動的コンテンツを追加した後にもう一度$("abbr.timeago").timeago()を呼び出すこともできます。しかし、新しい機能を追加するときにそれを追跡して覚えておくことは難しいかもしれません。そのため、代わりにlivequery pluginを使用しています。あなたのページにlivequeryスクリプトを含めると、次のと$("abbr.timeago").timeago();を置き換える:

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

これは一致するノードを動的に追加今どんな一致するノード上のtimeagoを可能にします。

+0

動的コンテンツを使用すると遅延が発生するという唯一の問題ですが、実際の時間は1秒後または2時間後に表示されます(多くの場合、悪い醜い日時 –

+0

あなたはCSSのあなたの中に設定することができます。 .timeago { 表示:なし } livequery機能で、その後 とコードだけ$(この).SHOW();その周り –

+0

@AmrElgarhy唯一の方法。デフォルトで空想的な日付を表示することです。 – rybo111

3

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()の機能の中に入れてください。

関連する問題