rails link_to: удаленный контент, загруженный ajax - PullRequest
4 голосов
/ 29 октября 2010

Привет всем, я работаю над приложением, и у меня возникают трудности с новым Rails 3 link_to. Вот ситуация - у меня есть два div на моей «домашней» странице, и каждый div заполняется в document.load с помощью ajax. Это работает как ожидалось.

В содержимом страниц, которые я загружаю в эти div, я хочу использовать функцию link_to ...: remote => true. Исходный код отображается, как и ожидалось, с тегом data-remote = "true", но когда я нажимаю на ссылки, они полностью игнорируются (ссылка рассматривается как обычная гиперссылка).

Я написал файлы .rjs, которые обрабатывают все правильно (потому что они работают в жестком коде), так что это не проблема.

Вот источник HTML для загруженного ajax контента:

<div>
  <a href="/cart/add/2" data-remote="true">Link A</a>
  <a href="/cart/add/1" data-remote="true">Link B</a> 
</div>

Нажатие на одну из этих ссылок, когда она обычно встроена в страницу, приводит к корректному обновлению моей корзины покупок ... однако, когда я динамически загружаю это содержимое на страницу с помощью AJAX, ссылка просто следует и игнорирует data-remote = "правда" ...

Первоначально я думал, что это как-то связано с неправильной загрузкой прототипа в AJAX, но я все это проверил, и это ничего не меняет ...

Я действительно запутался ... У кого-нибудь есть мысли по этому поводу?

# add method of controller
def add
  product = Product.find_by_id(params[:product_id])
  params[:quantity] ||= 1
  params[:price] ||= product.price

  unless product.nil?
    @line = session[:cart].purchase_lines.select {|l| l.product_id == product.id}.first
    unless @line.nil?
      @line.quantity = (@line.quantity + params[:quantity].to_i)
    else # create a new purchase_line in the cart
      @line = session[:cart].purchase_lines.build({ :product_id => product.id, :price => params[:price], :quantity => params[:quantity].to_i })
    end
  else
    flash[:error] = "Unable to add the selected product"
  end
end  

и мои RJS

# add.rjs
page.if page['product_' << @line.product_id.to_s] do
  page.replace 'product_' << @line.product_id.to_s, :partial => 'line'
page.else
  page.insert_html :bottom, 'cart', :partial => 'line'
end

page.replace_html 'sub_total', number_to_currency(session[:cart].sub_total, :unit => '$')
page.replace_html 'tax', number_to_currency(session[:cart].tax, :unit => '$')
page.replace_html 'total', number_to_currency(session[:cart].sub_total+session[:cart].tax, :unit => '$')
page.visual_effect :highlight, 'product_' << @line.product_id.to_s, :duration => 1

Ответы [ 2 ]

5 голосов
/ 29 октября 2010

Я почти уверен, что проблема в том, что когда ваша страница загружается в первый раз, используемая вами библиотека JavaScript Rails UJS (Prototype по умолчанию или jQuery и т. Д.) Привязывает слушателя к событию onclickЯкорный (ссылка) элемент.Однако, когда вы обновляете свою страницу новой разметкой динамически (в данном случае через ajax), новые теги привязки не получают эту привязку, потому что библиотека UJS делает это только при первой загрузке страницы.Если вы используете jQuery в качестве UJS, вам следует посмотреть вложение обработчика событий jQuery.live (), расположенное в jQuery API документах

Описание API выглядит следующим образом:

Описание: Прикрепите обработчик к событию для всех элементов, которые соответствуют текущему селектору, сейчас и в будущем.

В частности, вы должны дать div, который получитAJAX загрузил контент, скажем, идентификатор «cart-links», а затем добавил на страницу JavaScript, похожий на следующий:

$('#cart-links a').live('click', function() {
  // make your AJAX calls here
});

Я не уверен, что есть эквивалент Prototype, если вы этоusing.

Чем дальше я углубляюсь в javascript и Rails, тем больше я понимаю, что многие помощники Rails по javascript на самом деле усложняют разработку javascript и обработку AJAX, и я склоняюсь к использованию необработанного jQuery.

Удачи!

0 голосов
/ 01 ноября 2010

Я согласен с Патриком, вы, вероятно, связываетесь при загрузке DOM, поэтому любые новые элементы не связываются.Если используемый вами javascript (то есть Prototype) не имеет такой функциональности, как jQuery's live (), вы можете инкапсулировать логику связывания в функцию, которая отменяет привязку, а затем повторно связывает себя (может потребоваться пространство имен события, чтобы вы неснимите привязку с любых других обработчиков, но я не уверен, поддерживает ли Prototype события пространства имен), и затем вы можете вызывать эту функцию при вставке нового элемента.Кроме того, вы можете изолировать привязку к вновь созданному элементу вместо привязки к каждому элементу с таким именем класса или тегом.

И, как и Патрик, я также предпочитаю использовать raw jQuery.Таким образом, вам не нужно изучать, что делает rails.js, и использовать обходные пути для сценариев, когда он не делает то, что вы хотите.Как разработчик, вы должны знать, что вы хотите, чтобы ваш JavaScript делал, и делать это.Если вы предпочитаете использовать Prototype, вы все равно должны создать свой собственный rails.js, но, на мой взгляд, jQuery намного лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...