2 JQuery AJAX post req с тем же объектом

То, что я хочу сделать, это именно так:

<form>
    <input type="button" class="btn btn-warning" id="follow" value="Follow">  
</form>
<script type="text/javascript">

 $('#follow').click(function(){  
      $.ajax({ 
        url: '/follow'
        , type: 'POST'
        , cache: false
        , data: { user: '<%= username %>' }
        , complete: function() {


         },

        success: function(data) {

        },

        error: function() {

           console.log('process error');

        },
   });

   $('#follow').attr('value', 'Following');  
   $('#follow').attr('id', 'unfollow'); 
 });   

 $('#unfollow').click(function(){  
      $.ajax({ 
        url: '/unfollow'
        , type: 'POST'
        , cache: false
        , data: { user: '<%= username %>' }
        , complete: function() {


         },

        success: function(data) {


        },

        error: function() {

           console.log('process error');

        },
   });

   $('#follow').attr('value', 'Follow');  
   $('#follow').attr('id', 'follow'); 
 });           

</script>

Первый пост req работает отлично, но второй req нет. Когда я нажимаю кнопку, значение не изменяется, и я не получаю соответствующий пост req до /unfollow . В чем проблема?

Спасибо заранее!

2
добавлено отредактировано
Просмотры: 1
У вас есть дополнительная запятая после функций error: , это недопустимый Javascript.
добавлено автор Barmar, источник
@barmar: только в IE
добавлено автор mkoryak, источник

3 ответы

Связывание событий происходит, когда DOM загружается впервые. Когда вы меняете идентификатор динамически, это не приводит к изменению привязок. Для этого вам необходимо делегировать с помощью on() .

$(".btn").on("click", "#follow", function() {...});
$(".btn").on("click", "#unfollow", function() {...});

Другой вариант: not изменить идентификатор. Используйте один обработчик и проверьте, находится ли в настоящее время значение «Follow» или «Отменить подписку» и вызовите соответствующий URL-адрес.

$("#follow").click(function() {
    if ($(this).val() == "Follow") {
        $(this).val("Unfollow");
        var url = "/follow";
    } else {
        $(this).val("Follow");
        var url = "/unfollow";
    }
    $.ajax( {
        url: url
        , type: 'POST'
        , cache: false
        , data: { user: '<%= username %>' }
        , complete: function() {
        },

        success: function(data) {
        },
        error: function() {
           console.log('process error');
        }
    });
});
2
добавлено
Я могу ошибаться, но я думаю, что процесс делегирования заключается в том, что он привязывает обработчик к .btn , а обработчик проверяет, является ли целевой элемент («# follow») . Я не думаю, что это должны быть строгие отношения между родителями и детьми. Но если это так, ". Btn" может стать формой ".
добавлено автор Barmar, источник
Нам не нужны кнопки all , только одна кнопка. И это в форме.
добавлено автор Barmar, источник
Поскольку он привязывается к определенному идентификатору, а не к классу, он может быть довольно конкретным. Все, что имеет значение, это HTML, окружающий эту кнопку (если только он не планирует переносить этот идентификатор по всему документу, что очень плохой дизайн).
добавлено автор Barmar, источник
исправьте меня, если я ошибаюсь, но вы не можете делегировать таким образом. вы делегируете от родителя к дочернему элементу, но не от родителя к себе. для вашего кода для работы #btn должен стать документ
добавлено автор mkoryak, источник
только если все кнопки в форме :)
добавлено автор mkoryak, источник
По-видимому, я обожаю все кнопки. хороший звонок.
добавлено автор mkoryak, источник

Изменение идентификатора - не очень хорошая идея.

Вы можете получить правильный эффект, сохраняя идентификатор одинаковым и проверяя значение внутри одного обработчика кликов, например:

$('#follow').on('click', function(){
    if(this.value == 'Follow') {
        $.ajax({
            url: '/follow',
            type: 'POST',
            cache: false,
            data: { user: '<%= username %>' },
                complete: function() {
            },
            success: function(data) {
            },
            error: function() {
                console.log('process error');
            }
        });
        $(this).attr('value', 'Following'); 
    }
    else {
        $.ajax({ 
            url: '/unfollow',
            type: 'POST',
            cache: false,
            data: { user: '<%= username %>' },
            complete: function() {
            },
            success: function(data) {
            },
            error: function() {
                console.log('process error');
            }
        });
       $(this).attr('value', 'Follow'); 
    }
});

Вы можете упростить до одного блока $. Ajax() , в зависимости от того, насколько похожи функции успеха/ошибки/завершения.

Вы также можете перемещать утверждения, которые изменяют значение # follow внутри обработчика успеха. В противном случае значение кнопки покажет ложь хотя бы на мгновение или дольше, если произойдет ошибка ajax.

0
добавлено

Barmar правильный, но вы также не ссылаетесь на свой идентификатор правильно.

Вы ищете #follow после того, как вы уже изменили его на #unfollow :)

Вот пример того, что вы хотите сделать.

$(document).ready( function(){

   $("body").on("click", "#follow", function(){
      $(this).val("Unfollow");  
      $(this).attr("id","Unfollow"); 
   });

   $("body").on("click", "#Unfollow", function(){
      $(this).val("Follow");  
      $(this).attr("id","follow"); 
   }); 

});

And here it is at Jsfiddle

0
добавлено
Я думал, что это именно то, что я делаю.
добавлено автор Barmar, источник