2010-10-29 4 views
4

Salut tout le monde, je travaille sur une application et j'ai de la difficulté avec le nouveau Rails 3 link_to. Voici la situation - J'ai deux divs sur ma page "home", et chaque div est peuplé à document.load avec ajax. Cela fonctionne comme prévu.rails link_to: distant du contenu ajax

Dans le contenu des pages que je charge dans ces divs, je veux utiliser la fonction link_to ...: remote => true. La source se comporte comme prévu avec la balise data-remote = "true", mais lorsque je clique sur les liens, ils sont complètement ignorés (le lien est traité comme un lien hypertexte).

J'ai écrit des fichiers .rjs qui gèrent tout correctement (parce qu'ils fonctionnent en mode codé), donc ce n'est pas le problème.

est ici la source html pour le contenu ajax chargé:

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

En cliquant sur un de ces liens quand normalement intégrés dans la page provoque mon panier de mettre à jour correctement ... Cependant, quand je charge dynamique ce contenu dans la page avec AJAX, le lien suit juste et ignore le data-remote = "vrai" ...

A l'origine, je pensais que cela avait quelque chose à voir avec le prototype ne se charge pas correctement dans les choses AJAX, mais je ' J'ai vérifié tout ça et ça ne change rien ...

Je suis vraiment confus ... Quelqu'un at-il une idée à ce sujet?

# 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 

et mes 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 

Répondre

5

Je suis sûr que le problème est que lorsque votre page charge la première fois, les rails UJS bibliothèque javascript que vous utilisez (Prototype par défaut, ou jQuery, etc.) lie un écouteur à l'événement onclick de l'élément anchor (link). Cependant, lorsque vous mettez à jour votre page avec un nouveau balisage de façon dynamique (via ajax dans ce cas), les nouvelles balises d'ancrage ne reçoivent pas cette liaison, car la bibliothèque UJS ne fait rien lorsque la page est chargée. Si vous utilisez jQuery votre UJS vous devriez regarder dans la pièce jointe du gestionnaire d'événements jQuery.live() situé dans le jQuery API docs

La description de l'API est la suivante:

Description: Joindre un gestionnaire à l'événement pour tous les éléments qui correspondent au sélecteur de courant , maintenant et dans le futur .

Plus précisément, vous devriez donner à la div qui recevra le contenu chargé AJAX un identifiant disons « panier-liens », puis ajouter un peu de javascript à la page similaire à ce qui suit:

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

Je Je ne sais pas s'il y a un équivalent Prototype si c'est ce que vous utilisez. Plus je me suis familiarisé avec javascript et Rails, plus je me rends compte que beaucoup d'assistants javascript de Rails rendent le développement javascript et le traitement AJAX plus difficiles, et j'ai tendance à utiliser jQuery brut.

Bonne chance!

0

Je suis d'accord avec Patrick, vous êtes probablement lié lorsque le DOM est chargé afin que les éléments nouvellement ajoutés ne soient pas liés. Si le javascript que vous utilisez (c'est-à-dire Prototype) n'a pas de fonctionnalité comme live() de jQuery, vous pouvez encapsuler la logique de liaison dans une fonction qui se délie puis se redéfinit (vous pouvez déconnecter tous les autres gestionnaires, mais je ne suis pas sûr si Prototype prend en charge les événements d'espace de noms), et vous pouvez ensuite appeler cette fonction lorsque le nouvel élément est inséré. Vous pouvez également isoler votre liaison à l'élément nouvellement créé au lieu de lier tous les éléments avec ce nom de classe ou nom de tag.

Et comme Patrick, je préfère aussi utiliser jQuery brut. De cette façon, vous n'avez pas à apprendre ce que rails.js fait et bidouillez dans les solutions de contournement pour les scénarios où il ne fait pas ce que vous voulez. En tant que développeur, vous devez savoir ce que vous voulez faire de votre javascript, et le faire. Si vous préférez utiliser Prototype, vous devriez toujours créer votre propre rails.js, mais vraiment jQuery est beaucoup plus agréable à mon avis.

+0

Je suis d'accord ... jQuery est tellement mieux, mais je voulais essayer RJS/proto parce que je regardais les railscasts et ils ont fait paraître si facile – sethvargo

Questions connexes