.hasClass вкл.щелчок не регистрируется для вызова функции до второго щелчка ..асинхронный ajax?

#javascript #jquery #ajax #twitter-bootstrap #promise

#javascript #jquery #ajax #twitter-bootstrap #обещаю

Вопрос:

Некоторые кнопки с флажками (с использованием bootstrap) запускают вызов ajax get на.click, а активность отмеченных кнопок служит механизмом фильтрации.

Прямо сейчас, почему фильтрация корректно работает только при.click события второго щелчка (если нажат btn1, запускается ajax с /.one.two.three … и только при последующем нажатии btn2 он регистрируется как /.two.three .. и только при последующем нажатии btn3 он регистрируется как /.three ..? http://jsfiddle.net/ENJH9/2 /

В качестве альтернативы, если вызову refreshData() предшествует удаление класса на.click, данные обрабатываются правильно, но представление не отражает removeClass !? http://jsfiddle.net/ENJH9/3 /

Все кнопки начинаются с активного класса (http://getbootstrap.com/javascript/#buttons ):

 <div class="btn-group" data-toggle="buttons" id="theBtns">
  <label class="btn btn1 active">
    <input type="checkbox">one
  </label>
  <label class="btn btn2 active">
    <input type="checkbox">two
  </label>
  <label class="btn btn3 active">
    <input type="checkbox">three
  </label>
  <label class="btn btn4 active">
    <input type="checkbox">four
  </label>
</div>
  

Вот вызов .get, который следует за событием .click каждой кнопки:

 function refreshData() {

    console.log('started refreshData()')

    URL = '';

    var filtering = function() {

        if($(".btn1").hasClass("active")) { URL  = ".one"; }
        if($(".btn2").hasClass("active")) { URL  = ".two"; }
        ...

    console.log('done filtering: '   URL);

        return URL;
    };

    $.when( filtering() ).done(function() {

    console.log('now data refresh with %s filtering', URL)

    $.ajax({
      url:"http://localhost:4200/api/v1/data"   URL,
      method:'get',
      success: foundAllSuccess,
      error: foundError

    })

    });

}
  

И вот событие click с закомментированным removeClass (кнопки по-прежнему оставались визуально активными, а класс по-прежнему оставался в инспекторе, но сервер точно фильтрует с помощью этой настройки):

 $( ".btn1" ).click(function() {
  // if($(".btn1").hasClass("active")) {$(".btn1").removeClass("active"); console.log('hide btn1 data');}
  // else {$(".btn1").addClass("active"); console.log('btn1 data active');}
  refreshData();
}); // .btn1.click
  

Комментарии:

1. Как вы думаете, в чем смысл этого $.when(filtering()).done ? Вызов .when URL-адреса довольно бессмыслен, почему вы не можете просто вызвать его без .when ?

2. у него есть многоточие в filtering() , у него нет всей реализации фильтрации, включенной в его вопрос, потому что это, очевидно, не нужно. таким образом, вы можете предположить, что это длительная функция, поэтому использует .когда

3. @BenjaminGruenbaum the . когда была мысль о том, как заставить hasClass предшествовать вызову ajax .. затем URL добавляется к URL, который только что отредактирован.. любые другие предложения по получению URL-адреса, который точно отражает активные состояния btn?

4. Можете ли вы создать изолированную скрипку?

5. @BrianOgden спасибо за комментарий.. сообщение было обновлено, чтобы отразить, где используется URL var .. Любые предложения по точному представлению активных состояний btn с помощью URL var?

Ответ №1:

Во-первых, основная причина, по которой у вас возникла проблема, заключается в том, что bootstrap и jQuery не слишком удобно сочетаются друг с другом — по крайней мере, не в этом случае. Событие щелчка jQuery отправляется так рано, что это происходит до того, как bootstrap переключил «активный». Поэтому refreshData() работает с состоянием кнопки до щелчка, а не после щелчка. Это можно преодолеть с помощью a timeout() , чтобы отложить выполнение refreshData() до тех пор, пока bootstrap не сделает свое дело.

Во-вторых, вам не нужно переключаться active , поскольку bootstrap заботится об этом аспекте.

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

 function refreshData(e) {
    var URL = $(e.target).closest(".btn-group").find("label").map(function (i) {
        if ($(this).hasClass("active")) {
            return ['.one', '.two', '.three', '.four'][i];
        } else {
            return null;
        }
    }).get().join(''); //.map() returns an array, .join() concatenates the strings in the array into a single string.

    alert('now ajax call with filtering :'   URL);
}

$("#theBtns .btn").on('click', function (e) {
    setTimeout(function () {
        refreshData(e);
    }, 0);
}); 
  

ДЕМОНСТРАЦИЯ

Обратите внимание, что даже нулевой задержки достаточно для нашей цели, поскольку код, выполняемый из a setTimeout , будет выполняться в отдельном потоке событий при первой возможности после завершения текущего потока.

Может быть более «загрузочный» способ достижения той же цели, но я не собираюсь пробираться через тонны документации по начальной загрузке, чтобы узнать.