Assicurarsi che la funzione sia stata completata prima di consentire un'altra chiamata Ajax
Sto aggiornando un array salvato in un meta campo utenti utilizzando una funzione ajax.
I valori aggiunti all'array sono presi dagli attributi di dati all'interno dei tag che agiscono anche sul trigger per effettuare la chiamata ajax.
Sebbene la funzione funzioni il 95% delle volte, può essere un po 'incostante se i valori vengono salvati o meno. Sospetto che ciò sia dovuto al fatto che un utente può attivare queste chiamate ajax troppo rapidamente e non dare abbastanza tempo alla chiamata di funzione originale per salvare e aggiornare il meta campo.
Quale sarebbe il metodo migliore per garantire che la funzione attivata da ajax di aggiornamento del valore del campo meta sia stata completata prima di consentire l'esecuzione di nuovo della funzione?
Spero che questo abbia senso - inutile dirlo, per favore fatemi sapere se avete bisogno di ulteriori informazioni.
Grazie in anticipo!!
HTML di esempio
<div id="rjb_slots" class="slots">
<h5>Mon, 24th Aug 2020</h5>
<div class="slot">
<span class="time">10:30</span>
<a class="book" data-timestamp="1598265000" href="#"></a>
</div>
<div class="slot">
<span class="time">11:00</span>
<a class="booked" data-timestamp="1598266800" href="#"></a>
</div>
<div class="slot">
<span class="time">11:30</span>
<a class="booked" data-timestamp="1598268600" href="#"></a>
</div>
<div class="slot">
<span class="time">12:00</span>
<a class="book" data-timestamp="1598270400" href="#"></a>
</div>
<div class="slot">
<span class="time">12:30</span>
<a class="booked" data-timestamp="1598272200" href="#"></a>
</div>
<div class="slot">
<span class="time">13:00</span>
<a class="book" data-timestamp="1598274000" href="#"></a>
</div>
<div class="slot">
<span class="time">19:30</span>
<a class="book" data-timestamp="1598297400" href="#"></a>
</div>
</div>
Ajax .js
$('.slot').on('click', 'a.book', function(e) {
e.preventDefault();
var user = $('#rjb_day').attr( 'data-user' );
var stamp = $(this).attr( 'data-timestamp' );
// console.log(bookCap);
$(this).removeClass('book').addClass('booked');
$.ajax({
type: 'POST',
url: ajax_object.ajaxurl,
data: {
action: 'rjb_make_diary_slots',
user: user,
stamp: stamp
},
success: function(data) {
// This outputs the result of the ajax request
console.log(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
});
Funzione che aggiorna il metafield dell'utente
add_action( 'wp_ajax_rjb_make_diary_slots', 'rjb_make_diary_slots' );
function rjb_make_diary_slots() {
$user = $_POST['user'];
$stamp = array(
array(
'rjb_cal_day' => strtotime('today', $_POST['stamp']),
'rjb_cal_when' => $_POST['stamp'],
'rjb_cal_position_id' => '',
'rjb_cal_candidate_id' => ''
)
);
$calendar = get_user_meta( $user, 'rjb_cal', true);
$stamps = !empty($calendar) ? $calendar : array();
$new_stamp = array_merge($stamps, $stamp);
usort($new_stamp, function($a, $b) {
return $a['rjb_cal_when'] <=> $b['rjb_cal_when'];
});
update_user_meta( $user, 'rjb_cal', $new_stamp);
$log = print_r($stamp);
wp_die($log);
}
Esempio di un valore memorizzato nel rjb_cal
campo meta utente
array (
[0] => array (
[rjb_cal_day] => 1598227200
[rjb_cal_when] => 1598266800
[rjb_cal_position_id] =>
[rjb_cal_candidate_id] =>
)
[1] => array (
[rjb_cal_day] => 1598227200
[rjb_cal_when] => 1598268600
[rjb_cal_position_id] =>
[rjb_cal_candidate_id] =>
)
[2] => array (
[rjb_cal_day] => 1598227200
[rjb_cal_when] => 1598272200
[rjb_cal_position_id] =>
[rjb_cal_candidate_id] =>
)
)
Risposte
Di solito uso le classi CSS per controllare le richieste AJAX che interessano un elemento specifico. In questo modo puoi impedire richieste AJAX indesiderate su quell'elemento, mentre altre richieste AJAX potrebbero ancora essere attivate, essendo associate ad altri elementi.
$('.slot').on('click', 'a.book', function(e) {
e.preventDefault();
// Check if doing ajax
if($(this).hasClass("doing-ajax")) return false;
$(this).addClass("doing-ajax");
var user = $('#rjb_day').attr( 'data-user' );
var stamp = $(this).attr( 'data-timestamp' );
// console.log(bookCap);
$(this).removeClass('book').addClass('booked');
$.ajax({
context: $(this),
type: 'POST',
url: ajax_object.ajaxurl,
data: {
action: 'rjb_make_diary_slots',
user: user,
stamp: stamp
},
success: function(data) {
// This outputs the result of the ajax request
console.log(data);
// Remove "doing-ajax" class
$(this).removeClass("doing-ajax");
},
error: function(errorThrown){
console.log(errorThrown);
// Remove "doing-ajax" class
$(this).removeClass("doing-ajax");
}
});
});
Non dimenticare di aggiungere la context
proprietà all'oggetto di configurazione del tuo AJAX, come ho fatto nell'esempio precedente.
Puoi utilizzare due approcci per impedire all'utente di fare clic sul tuo elem prima di completare completamente l'ajax. 1.Visualizza il caricatore e blocca quell'elemento in modo che nessuno possa eseguirlo fino al completamento dell'ajax. 2.usare una variabile globale isAjaxProcess = false; ora nel tuo codice crea un blocco di condizione If(isAjaxProcess === false) { isAjaxProcess = true: il tuo codice ajax va qui. E imposta isAjaxProcess su false nel tuo blocco di successo ajax. }