#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
, будет выполняться в отдельном потоке событий при первой возможности после завершения текущего потока.
Может быть более «загрузочный» способ достижения той же цели, но я не собираюсь пробираться через тонны документации по начальной загрузке, чтобы узнать.