2017-02-02 3 views
0

J'ai un modèle Comment avec 2 vues: 1 pour le commentaire du parent et un pour les réponses. La vue parente fonctionne correctement mais, pour une raison quelconque, ma vue de réponse est appelée deux fois, ce qui crée deux objets de réponse à la fois. Alors d'abord voici un bouton .reply l'utilisateur clique qui ouvre le formulaire de commentaires et de donner cette forme de commentaires une valeur onclick de reply_comment():Vue étant appelée deux fois/objet créé deux fois

$('.reply').on('click', function(e) { 
    var clone = $('.comment_form').clone(); 
    parent_id = $(this).closest('.comment_div').data('comment_id'); 
    $(this).closest('.comment_div').after(
     clone 
    ); 
    clone.addClass('reply_comment_form').removeClass('comment_form'); 
    clone.attr('onclick', 'reply_comment()'); 
    clone.data('comment_id', parent_id); 



    $(this).next().css('display', 'inline-block'); 
    $(this).css('display', 'none'); 
    $('.reply_comment_form').css('padding', '1px'); 

}); 

Et voici la fonction réelle:

function reply_comment() { 
    $('.reply_comment_form').on('submit', function (e) { 
     e.preventDefault(); 
     parent_id = $('.reply_comment_form').data('comment_id'); 

     $.ajax({ 
      type: 'POST', 
      url: '/comment_reply/', 
      data: { 
       reply_text: $(this).find('.comment_text').val(), 
       parent_id: parent_id, 
       id: path, 
       csrfmiddlewaretoken: $("input[name='csrfmiddlewaretoken']").val(), 
      }, 
      success: function(data) { 
       $('.reply_comment_form').replaceWith("<div class='comment_div new_comment'><div class='left_comment_div'>" + 
       "<div class='username_and_votes'><h3><a href='#' class='username'>" + data.username + 
       "</a></h3><span class='upvotes' style='margin: 0 6'>0</span><span class='downvotes'>0</span></div><br><p>" + data.reply_text + 
       "</p></div><a href='#'><span class='comment_delete'>x</span></a></div>"); 
       $('.new_comment').css({ 
        'width': '72%', 
        'margin': '0 70 10 0', 
        'float': 'right', 
       }); 
       $('.new_comment').next().css('clear', 'both'); 
       $('.new_comment').prev().find('.cancel_comment').css('display', 'inline-block') 
        .find('.cancel_comment').css('display', 'inline-block'); 
      } 

     }); 


    }); 
} 

cet appel AJAX ajoute la réponse avec succès, et est envoyé à cette vue pour l'enregistrer dans la base de données:

def comment_reply(request): 
    print('reply') 
    if request.is_ajax(): 
     comment = CommentForm(request.POST or None) 
     reply_text = request.POST.get('reply_text') 
     id = request.POST.get('id') 
     parent_id = request.POST.get('parent_id') 
     parent = Comment.objects.get(id=parent_id) 

     if comment.is_valid(): 
      comment = Comment.objects.create(comment_text=reply_text, destination=id, user=request.user, parent_id=parent_id, parent_comment=parent) 
      username = str(request.user) 
      return JsonResponse({'reply_text': reply_text, 'username': username}) 

Très bien, sauf que cette vue est appelée deux fois et crée 2 objets Comment. Une idée de pourquoi ça fait ça?

+0

Le code semble inutilement compliqué. Je pense que vous n'avez pas besoin d'intégrer le 'onsubmit' dans la fonction' reply_comment() 'du tout. Je pense que le 'onclick' que vous avez là pourrait être exécuté plusieurs fois, puis la chose' onsubmit' est liée deux fois aussi. – yedpodtrzitko

+0

J'ai essayé '$ ('. Reply_comment_form'). On ('submit', function {' par lui-même mais il n'a pas été appelé.Faites l'onsubmit think est la seule option que j'ai. – Zorgan

+1

bien sûr, parce que l'élément ne Essayez au lieu de cela: '$ (document) .on ('submit', '.reply_comment_form', function (e) {...' – yedpodtrzitko

Répondre

0

Résumant les commentaires dans une réponse:

Je ne sais pas exactement pourquoi il est limité à deux reprises, mais je crois que les onclick même pourrait être déclenché à plusieurs reprises, ce qui conduit à un multiple liaison de onsubmit

différence entre ces deux pièces:

$('.reply_comment_form').on('submit', function(e) { 

et

$(document).on('submit', '.reply_comment_form', function(e) { 

Le code est exécuté ondomready (c.-à-d. lorsque le document DOM est prêt), et à ce moment .reply_comment_form n'existe pas encore, l'événement submit n'est pas accroché à quoi que ce soit.

La deuxième pièce est exécutée dans une portée de $(document) qui existe et le deuxième paramètre dans on() indique les éléments auxquels elle doit être limitée. Ses performances sont un peu pires (puisqu'il faut regarder tout le document), mais ça marche.