首页 > 解决方案 > jquery ajax功能撤消没有按预期工作

问题描述

我有一个单词列表,希望用户知道一个单词时能够单击一个按钮,然后这个单词将变为“已知”,css 类将更改,字段word_is_known将从更改FalseTrue。但我也希望用户能够撤消此操作。这似乎第一次工作正常,即如果用户单击然后取消单击。但是如果用户再次点击同一个词,它会在模型​​中创建另一个条目,KnownWord而不是更新现有的条目。我一直在无休止地玩这个,但无法弄清楚。

这是我的jQuery:

$(document).ready(function() {
  var known_words = 0;
  var clicked_words = [];
  var unclicked_words = [];
  $(".word_known").click(function() {
    var reference = this;
    var objectpk = $(this).data('objectpk');
    var userpk = $(this).data('userpk');
    $(this).toggleClass('increment');
    if ($(this).hasClass('increment')) {
    known_words++;
    clicked_words.push($(this).data('word'));
    add_object = 'add';
    $.ajax({
      async: false,
      url: "/videos/songs/vocab/known/"+objectpk+"/"+userpk+"/",
      data: {'action': add_object, 'known_words': known_words, 'clicked_words': clicked_words},
      success: function(data) {
    $(reference).removeClass("btn-warning");
    $(reference).addClass("btn-success");
    $(reference).text("Known");
  },
      failure: function(data) {
        alert("There is an error!")
      },
      contentType: "application/x-www-form-urlencoded; charset=utf-8",
      })
   console.log(known_words, clicked_words);
 }
  else {
  known_words--;
  unclicked_words.push($(this).data('word'));
  remove_object = 'remove';
  $.ajax({
    async: false,
    url: "/videos/songs/vocab/known-undo/"+objectpk+"/"+userpk+"/",
    data: {'action': remove_object, 'known_words': known_words, 'unclicked_words': unclicked_words},
    success: function(data) {
  $(reference).removeClass("btn-success");
  $(reference).addClass("btn-warning");
  $(reference).text("Yes");
},
    failure: function(data) {
      alert("There is an error!")
    },
    contentType: "application/x-www-form-urlencoded; charset=utf-8",
    })
 console.log(known_words, unclicked_words);
}
})
});

我的看法:

def word_known(request, object_pk, pk_user):
    if request.method == 'POST':
        pass
    elif request.method == 'GET' and request.GET['action'] == 'add':
        known_words = request.GET.get('known_words', '')
        clicked_words = request.GET.getlist('clicked_words[]')
        request.session['known_words'] = known_words
        request.session['clicked_words'] = clicked_words
        user = request.user
        song = models.Song.objects.get(pk=object_pk)
        for word in set(clicked_words):
            models.KnownWord.objects.get_or_create(word_is_known=True,
            word=word, user=user, song=song)

    print('The number of known words is {} and clicked words are {}'.format(known_words, clicked_words))

    return HttpResponse(json.dumps(clicked_words), content_type='application/json')

def word_known_undo(request, object_pk, pk_user):
    if request.method == 'POST':
        pass

    elif request.method == 'GET' and request.GET['action'] == 'remove':
        known_words = request.GET.get('known_words', '')
        unclicked_words = request.GET.getlist('unclicked_words[]')
        request.session['known_words'] = known_words
        request.session['unclicked_words'] = unclicked_words
        user = request.user
        song = models.Song.objects.get(pk=object_pk)
        for word in set(unclicked_words):
            models.KnownWord.objects.filter(word=word,
                user=user, song=song).update(word_is_known=False)
    print('The number of known words is {} and deleted words are {}'.format(known_words, unclicked_words))

    return HttpResponse(json.dumps(unclicked_words), content_type='application/json')

KnownWord型号:

class KnownWord(models.Model):
    word_is_known = models.BooleanField(default=False)
    word = models.CharField(max_length=25)
    user = models.ForeignKey(User, related_name="known_words", on_delete=models.CASCADE)
    song = models.ForeignKey(Song, on_delete=models.CASCADE, null=True, blank=True)
    movie = models.ForeignKey(Movie, on_delete=models.CASCADE, null=True, blank=True)

以及我模板中的相关部分:....

  {% elif item.0 in known_words %}
    <a href="javascript:" class="word_known_undo btn btn-success btn-sm" data-word="{{item.0}}" data-objectpk="{{object_pk}}" data-userpk="{{user_pk}}">Known</a>
    {% else %}
    <a href="javascript:" class="word_known btn btn-warning btn-sm" data-word="{{item.0}}" data-objectpk="{{object_pk}}" data-userpk="{{user_pk}}">Yes</a>
    {% endif %}

标签: pythonjquerypython-3.xajax

解决方案


  • 您的问题是您没有从另一个数组中删除该值

  • 它的所有关于数组push , check , splice看下一个例子

$(document).ready(function(){
  var clicked_words = [] ;
  var unclicked_words = [];
  var known_words = 0;
  $(document).on('click' ,'.word_to_know:not(.pending)' , function(){   //<<<<<<<<<<< here
    var This = $(this);
    var This_data_word = This.data('word');
    This.addClass('pending').toggleClass('increment');
    if(This.hasClass('increment')){
      known_words++;
      clicked_words.push(This_data_word);
      unclicked_words = remove_if_in_array(unclicked_words , This_data_word);
      
      // inside ajax callback   //<<<<<<< here
      setTimeout(function(){ //<< don't use this .. this is just for the demo
       This.removeClass('pending');  // <<<<<<<< here
      } , 2000); //<< don't use this .. this is just for the demo
    }else{
      known_words--;
      unclicked_words.push(This_data_word);
      clicked_words = remove_if_in_array(clicked_words , This_data_word);
      
      // inside ajax callback   //<<<<<<< here
      setTimeout(function(){ //<< don't use this .. this is just for the demo
       This.removeClass('pending');  // <<<<<<<< here
      } , 2000); //<< don't use this .. this is just for the demo
    }
    
    console.log('known_words '+known_words);
    console.log('clicked_words [' +clicked_words +']');
    console.log('unclicked_words [' + unclicked_words+']');
  });

});

// remove value if is in the array
function remove_if_in_array(array , value){
  var index = array.indexOf(value);
  if (index > -1) {
    array.splice(index, 1);
  }
  return array;
}

// update value if is in the array
function update_if_in_array(array , value){
  var index = array.indexOf(value);
  if (index > -1) {
    array.splice(index, 1);
  }
  array.push(value);
  return array;
}
a.increment{
  border : 1px solid #000;
  background : green;
  color : #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href="javascript:" class="word_to_know word_known_undo btn btn-success btn-sm" data-word="word_1_known" data-objectpk="{{object_pk}}" data-userpk="{{user_pk}}">Known</a>

<a href="javascript:" class="word_to_know word_known_undo btn btn-success btn-sm" data-word="word_2_yes" data-objectpk="{{object_pk}}" data-userpk="{{user_pk}}">Yes</a>

<a>我为所有命名它的人创建了一个类,word_to_know您可以随心所欲地更改任何内容..但我希望您明白这一点


推荐阅读