Рекомендации по использованию AJAX без встроенных помощников Rails? - PullRequest
3 голосов
/ 29 апреля 2009

В моем приложении для блога некоторые сообщения отображаются в виде выдержек, то есть пользователь видит первые (скажем) 500 символов и может щелкнуть ссылку, чтобы просмотреть все сообщение. Вот соответствующий частичный:

<% href = url_for post_path(:id => post) %>

<h1 class="title"><%= post.title %></h1>
<h2 class="published_on"><%= post.author %> wrote this <%= time_ago_in_words(post.published_on)%> ago</h2>
<div class="body">
  <% if defined?(length) %>
    <%= truncate_html(post.body, :length => length, :omission => "&hellip;<h1><a class='more' href=\"#{href}\">Click here for more!</a></h1>") %>
  <% else %>
    <%= post.body %>
  <% end %>
</div>

Тем не менее, вместо "Нажмите здесь для более!" Перенос пользователя на отдельную страницу, я бы хотел, чтобы остальная часть поста была заполнена. В настоящее время я реализую это, поместив приведенный выше фрагмент в следующий div:

<div class="post" id="post_<%= post.id %>">
  <%= render :partial => 'post_content', :locals => { :post => post, :length => 500 } %>
</div>

Затем я использую идентификатор этого div в моем application.js для выполнения AJAX:

$(document).ready(function() {

  $("a.more").click(function() {
    var url = $(this).attr('href');
    var id = url.split("/")[2]
    $.get(url, null, function(data) {
      $("#post_" + id).html(data);     
    });
    return false;
  });

});

Это явно отвратительно - я не хочу, чтобы мой javascript зависел от местоположения идентификатора поста в href ссылки, но я не знаю другого способа узнать, какой пост он получает, и следовательно, в какой div должен быть вставлен контент.

Какой лучший способ сделать это? Должен ли я просто вернуться к использованию помощников рельсов AJAX?

Ответы [ 3 ]

7 голосов
/ 02 мая 2009

Гораций, ты прав. Вам не нужны помощники Rails вообще. Чтобы достичь ненавязчивой нирваны JavaScript, вам следует избегать их (извините, Марк!)

Ненавязчивый JS означает избегать встроенного JS, где это возможно. В самом деле, старайтесь держать вещи слабо связанными, но не полностью отделенными. В приведенном нами примере это легко, потому что у нас есть URL из HREF для работы. Вашему JS не нужно ничего «знать» о том, как запросить.

Вот как отправлять через ссылку от HREF вслепую, и заставить Rails отвечать ответом ajax (т.е. без макета).

РЕШЕНИЕ:

<!------- Your HTML ------>
<h1 class="title">Schwein Flu Strikes Again</h1>
<h2 class="published_on">B.Obama wrote this 2 seconds ago</h2>
<div class="body">
    SUMMARY SUMMARY
    <h1><a class='more' href="/post/1234">Click here for more!</a></h1>
</div>
/********* Your JavaScript ***********/
$(document).ready(function() {</p>

<p>$("a.more").click(function() {
    $containing_div = $(e).parents('div.body');
    var url = $(this).attr('href');
    $.ajax({
        beforeSend  : function(request) { request.setRequestHeader("Accept", "text/javascript"); },
                        /* Included so Rails responds via "format.js" */
        success     : function(response) { $(containing_div).empty.append(response); },
        type        : 'get',
        url         : url
    });
    return false;
  });</p>

<p>});
########### Your Controller ###########
def show
  @article = Post.find(param[:id])
  respond_to do |format|
    format.html { render :action => "show" and return  }
    format.js { render :partial => "post_content", :layout => false and return }
  end
end

Это также предполагает, что у вас есть маршруты RESTful или аналогичные для обработки / post /: id

И мы закончили! Я верю, что в этом есть что-то для всех нас. : D

1 голос
/ 18 июня 2011

В этом случае, я не думаю, что у вас вообще должен быть вызов AJAX. У вас уже есть весь контент исходного поста в post.body (вы не получили только 500 символов из БД). Вместо того, чтобы использовать JQuery для вызова ajax, используйте его, чтобы скрыть контент после 500 символов, а затем, когда пользователь нажимает на ссылку «больше», на которой показан остальной элемент div. Вы можете сделать это полностью на стороне клиента и сохранить себе AJAX.

В вашем частичном:

<div class="body">
  <%= post.body %>
</div>

Ваш JQuery:

var fullText = $('div.body').html();
$('div.body').html(fullText.slice(0,499) + '<a class="more" href=\"#\">Click here for more!</a>');
$('a.more').live('click', function(event) {
  this.parent().html(fullText);
  return false;
}
0 голосов
/ 29 апреля 2009

По моему мнению, для такого рода проблем вы должны использовать помощников рельсов.

HTML будет выглядеть так:

My post bla bla bla <span id="more_of<%=post.id%>">more</span>

Чем больше ссылка будет:

<%= link_to_remote( "more",:update => "more_of_#{your_post.id}",:url =>{:controller => "myposts", :action=>"show_more", :id => your_post.id}, %>

И контроллер будет делать что-то вроде:

post = Post.find_by_id(params[:id])
render :text => post.content.slice(100..post.content.size) 

Другой способ, который может быть таким же хорошим, - это загрузить все, а затем спрятать его:

bla bla bla this is my post blah <div style="display:none" onclick="this.style.display='block';">and this is the rest of the article</div>

(щелчок тега div в IE может прерваться, но это поможет вам понять)

Для меня это будет лучший путь, если у вас нет веских причин избегать помощников рельсов.

Надеюсь, это поможет

...