Рекомендации по загрузке содержимого страницы с помощью запроса AJAX в Rails3?

Предположим, у вас есть страница с двумя столбцами содержимого. По какой-либо причине вы хотите получить содержимое HTML в одном из этих столбцов после загрузки страницы с помощью запроса AJAX. Пользователю не нужно предпринимать действия для загрузки содержимого (без ссылки на ссылку или отправки формы), это просто происходит автоматически.

Я легко могу это сделать, возвращая пустой разделитель div в основном ответе

<div id="pink-dancing-elephants"></div>

а затем добавьте немного jQuery на страницу

$.ajax({
    url: "/elephants/dancing/pink",
    cache: false,
    success: function(html){
      $("#pink-dancing-elephants").append(html);
    }
});

и получим действие, в котором ответы на/слоны/танцы/розовые возвращают соответствующий кадр HTML.

Все это прекрасно работает, но мне интересно, не хватает ли у меня функции Rails3, которая упростит это. Например. Я ищу способность иметь возможность просто поставить что-то вроде следующего в главном представлении, а оставшаяся часть этого происходит с помощью "волшебства"

<%= render :url=>"/elephants/dancing/pink", :remote => true %>

Я что-то пропустил?

Ответы

Ответ 1

Я думаю, что я изначально был набросок, на самом деле лучший подход.

Сначала поставьте пустой, разделитель div в ваш основной вид

<div id="recent_posts"></div>

а затем добавьте немного jQuery на страницу

$.ajax({
    url: "/posts/recent",
    cache: false,
    success: function(html){
      $("#recent_posts").append(html);
    }
});

и у вас есть действие, которое ответы на /posts/recent возвращают blob HTML, который вы хотите заполнить div. В действии, вызванном запросом AJAX, вы хотите сделать с помощью: layout = > false, чтобы вернуть возвращенный blob HTML из всего кадра. Например.

# posts_controller.rb
def recent
  @recent_posts = #whatever
  render :layout => false
end

Это приведет к отображению шаблона в views/posts/recent.html.erb, а затем jQuery позаботится о вставке визуализированного содержимого в ваш разделитель div.

Ответ 2

Я использую метод, описанный в комментарии @cailinanne к сообщению Dan L, и это сработало для меня. Мне нравится читаемость тега данных, который привязан к div. Внутри вашего html вы можете точно увидеть, что будет загружаться в этот div, и вам не нужно добавлять новые JS, если вы хотите добавить эту функцию в несколько div или страниц.

Из этой статьи: http://tech.thereq.com/post/16479390885/loading-page-content-via-ajax-in-rails-3-1

Самый простой способ сделать это с помощью метода загрузки jQuery.

$("#comments").load("/blogs/2/comments");

Неловкая часть - это путь AJAX (/blogs/2/comments), который явно изменяется в зависимости от того, какой блог мы просматриваем. Если бы мы точно следили за документацией jQuery, мы могли бы просто плюхнуть тег script в середине нашего тела HTML, так что в нашем файле шаблона мы могли бы иметь что-то вроде

# show.html.erb

<div id="comments"></div>
<script>
  $("#comments").load("<%= blog_comments_path(@blog)%>");
</script>

Тьфу. Не поклонник javascript, смешанный с моими файлами шаблонов.

Что делать? Следуйте шаблону, предложенному Rails UJS, и воспользуйтесь новыми атрибутами данных HTML.

Во-первых, когда вы хотите загрузить контент AJAX на своей странице, сделайте следующее в своем шаблоне

#show.html.erb

<div id="comments" data-load="<%= blog_comments_path(@blog. :format => :js)%>">
</div>

Во-вторых, добавьте следующее в свой application.js

# application.js or any JS file loaded within application.js

$("div[data-load]").filter(":visible").each(function(){

  var path = $(this).attr('data-load');
  $(this).load(path);

});

В-третьих, настройте маршрут, соответствующий запросу get-blog_comments (введите rake routes, чтобы увидеть, как ваши маршруты будут названы)

# routes.rb

# ajax load at page load
  get "/blogs/comments" => "blogs#comments"

И вуаля! Ваши комментарии div волшебным образом будут заполнены тем, что возвращается по пути/blogs/3/comments!

Ответ 3

Существует простой способ для источника, просто добавьте respond_to :html, :js к контроллеру и создайте представления *.js.erb в каталоге app/views/. Затем ваш контроллер сможет ответить на формат javascript, и вы можете написать javascript с ruby-кодом в файлах *.js.erb.
Проверьте это: ненавязчивый javascript в Rails 3

Ответ 4

Если вы хотите использовать подход, предложенный OP, я бы рекомендовал переместить его в отдельный файл application.js и использовать ненавязчивый JS. Я бы не рекомендовал размещать JS inline на самой странице.

# index.html.erb
<div id="content"></div>

# application.js
$(function() {
  $.ajax({
    url: "...",
    success: function (html) {
      $("#content").append(html);
    }
  });
});

# controller.rb
# empty placeholder
def index
end

Это автоматически отменяет запрос ajax, без необходимости размещать его на каждой странице. Это лучше. Я бы не назвал его оптимальным, но слегка м