format.js не манипулирует dom, если включено кэширование действий
Примечание: здесь я представляю логику того, что я делаю.
Что я делаю:
Подумайте об основных действиях с индексами, где мы перечисляем продукты и нумерацию страниц. Теперь, используя опцию remote-true, я включил пагинацию на основе ajax. Пока все работает отлично. Посмотрите на пример кода.
Контроллер продуктов:
def index
@products = Product.paginate(:order =>"name ASC" ,:page => params[:page], :per_page => 14)
respond_to do |format|
format.html # index.html.erb
format.json { render json: @products }
format.js
end
end
index.html.erb
<h1>Products</h1>
<div id="products">
<%= render "products/products" %> // products partial is just basic html rendering
</div>
<script>
$(function(){
$('.pagination a').attr('data-remote', 'true')
});
</script>
Index.js.erb
jQuery('#products').html("<%= escape_javascript (render :partial => 'products/products' ) %>");
$('.pagination a').attr('data-remote', 'true');
Так в чем проблема:
Теперь я хочу включить кеширование действий на этом. Но файл index.js.erb не манипулирует DOM. Если я удалю функцию remote-true, то с кэшированием все будет в порядке.
Для кэширования действий я добавил эту строку в верхней части контроллера:
caches_action :index, :cache_path => Proc.new { |c| c.params }
Какие-либо предложения?
Обновить:
Проблема в том, что jquery-код не выполняется. Из этого вопроса
Я узнал, что не так. JQuery фактически окружает входящий скрипт так, что браузер оценивает входящий код. Но механизм кэширования просто сохраняет код в виде текста и при повторном запросе возвращает код в виде текста, но не оценивает его. Следовательно, нужно явно проверить код
Но как решить эту проблему??
4 ответа
Я не понимаю, в чем проблема с использованием remote: true
, Кто-то еще предложил использовать .ajax
вместо remote: true
, но это именно то, что делает удаленная функциональность, поэтому не должно быть никакой разницы.
Другой ответ имеет код, который явно использует jQuery.ajax
, но единственная разница в их коде по сравнению с тем, что делает удаленная функциональность, заключается в том, что они указывают явный dataType
, Вы можете сделать это с remote: true
хоть.
В вашей HTML-ссылке вам просто нужно указать data-type="script"
, Или, основываясь на вашем опубликованном JS, вы сделаете это:
$(function(){
$('.pagination a').attr('data-remote', 'true').attr('data-type', 'script');
});
РЕДАКТИРОВАТЬ: Кроме того, я написал более подробно об атрибуте типа данных и как он работает с Rails здесь: http://www.alfajango.com/blog/rails-3-remote-links-and-forms-data-type-with-jquery/
После некоторых проб и ошибок, я думаю, у меня есть обходной путь.
Ссылки на страницы
Вместо
$(function() { $('.pagination a').attr('data-remote', 'true') });
использование
$(function() {
$('.pagination a').click(function() {
$.ajax({
url: this.href,
dataType: 'script'
});
return false;
});
});
поэтому ответ, созданный сервером приложений, будет запускаться как JavaScript
контроллер
затем измените caches_action
линия к
caches_action :index, cache_path: proc { |c| c.params.except(:_).merge(format: request.format) }
так как AJAX добавляет _
параметры для какой-то метки времени
Надеюсь, это работает:)
Я думаю, что нашел решение этой проблемы. У меня есть контроллер, который имеет caches_action
для действия, которое использует format.js для извлечения некоторых данных через ajax, и это не сработало из коробки.
Я обнаружил, что, несмотря на то, что запрос передается на сервер, и сервер правильно анализирует запрос и "отрисовывает" index.js.erb
шаблон, ничего не обновлялось в DOM. Ваше решение с $.ajax
а также dataType:'script'
Исправил проблему для меня, однако, мне не нравилось делать jquery для привязки к клику по ссылке, что должно происходить по умолчанию... Я смог заставить его работать правильно, изменив мой link_to
к этому:
= link_to "click me", user_action_path(params), remote: true, data:{type: 'script'}
Надеюсь это поможет!
У меня возникла та же проблема, но в моем приложении 3.0.3 с:remote => true я добавил:'data-type' =>: script и работал нормально.
Тем не менее, в моем случае, я не вижу улучшения при загрузке списка ajax.