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 }
Любые предложения?
Update:
Проблема заключается в том, что код jquery не выполняется. Из этого вопроса
Я понял, что случилось. jQuery фактически окружает входящий script так, чтобы браузер оценивал входящий код. Но кеширование mechansim просто сохраняет код как текст, и когда один повторный запрос, он возвращает код как текст, но не оценивает его. Таким образом, нужно явно вычислить код
Но как решить эту проблему?
Ответы
Ответ 1
Я не вижу, что проблема должна быть с использованием 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');
});
EDIT: Кроме того, я написал более подробную информацию об атрибуте типа данных и о том, как он работает с Rails здесь: http://www.alfajango.com/blog/rails-3-remote-links-and-forms-data-type-with-jquery/
Ответ 2
После некоторых проб и ошибок, я думаю, что у меня есть работа.
Ссылки на страницы
Вместо
$(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 добавляет параметры _
для какой-то отметки времени
Надеюсь, это работает:)
Ответ 3
У меня была та же проблема, но в моем приложении 3.0.3: remote = > true Я добавил: 'data-type' = > : script и работал нормально.
Однако, в моем случае, я не вижу улучшения при загрузке ajax в список.
Ответ 4
Думаю, я нашел решение этой проблемы. У меня есть контроллер, который имеет 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'}
Надеюсь, это поможет!