2012-04-02 40 views
7

Ho una funzione javascript che deve fare un calcolo numerico. Alcuni dei numeri utilizzati in questo calcolo sono memorizzati in un database e variano a seconda di come un utente compila un modulo online. Una volta che l'utente compila il modulo, farà clic sul pulsante CALCOLA. A questo punto, nella funzione JS, vorrei usare ajax per ottenere valori da un database che corrisponde ad un altro valore scelto dall'utente.aggiornamento variabile javascript con ajax in tempo reale

Per un semplice esempio: ci sono 3 taglie di t-shirt, con prezzi diversi in base a ciascuna dimensione (memorizzate nel database). L'utente sceglie la dimensione e quando fa clic su CALCULATE, utilizzo ajax per ottenere il prezzo associato alla dimensione scelta.

La domanda è, voglio usare ajax per aggiornare alcune variabili che userò più avanti nello script. Il modo in cui sto provando a farlo ora non funziona, la variabile nello script non viene aggiornata da ajax, posso solo accedere al valore dal database all'interno della funzione success della chiamata ajax. Capisco perché ajax è asincrono per sua natura, e ci vuole del tempo, in attesa che i dati vengano restituiti dal server, mentre la funzione continua a funzionare

Nell'esempio seguente, la chiamata ajax restituisce i dati JSON e ho una funzione chiamata isjson() che verifica se la stringa restituita è in effetti dati JSON.

codice Esempio:

function calculate_cost(){ 

    var price = 0; 
    var size = $('form#tshirt_form [name="size"] option:selected').val(); 
    $.ajax({ 
     url:'my_script.php', 
     type:'post', 
     data:'select=price&table=tshirts.prices&where=size = "' + size + '"', 
     success:function(data){ 
      if(isjson(data)){ 
       data = $.parseJSON(data); 
       data = data[0]; 
       price = data['price']; 
      }else{ 
       //display error getting data 
      } 
     } 
    }); 
    // continue code for calculation 
    // this alert will display "0", but I want the price from the database in there 
    alert(price); 
    //perhaps do other ajax calls for other bits of data 
    //... 
    return final_price; 
} 

Qualcuno sa come posso fare questo, aggiornando le variabili con Ajax in tempo reale ??

Grazie mille!

** EDIT **

Grazie a tutti per l'aiuto, ho capito su ajax essere asincrono. Mi piacerebbe davvero una risposta in cui non devo continuare il calcolo all'interno della funzione success, perché il mio problema reale riguarda molti valori di un numero piuttosto elevato di tabelle diverse. Mi piacerebbe anche essere in grado di espandere il calcolo in futuro senza che diventi troppo complicato. Se questo non è possibile, mai, allora dovrò vivere con quello. ;-)

** EDIT 2 **

OK, abbiamo ottenuto la risposta: naturalmente è proprio vicino alla parte superiore della pagina docs,: -/dispiace. La proprietà async nella chiamata ajax jQuery. http://api.jquery.com/jQuery.ajax/

+5

'dati: 'query = seleziona prezzo da tshirts.prices dove size ="' + size + '"', 'Per favore non farlo. Cosa succede se 'data: 'query = utenti della tabella di rilascio'' – karim79

+2

Spero che tu faccia qualche risanamento di input mega-intelligente da' data: query = 'parte – bububaba

+1

Sembra che tu sia' rendendo molto facile per qualcuno eseguire un attacco di SQL injection. Il tuo codice lato server sta per eseguire qualsiasi query che viene lanciata su di esso. Sarebbe meglio memorizzare l'istruzione SQL nel codice PHP e passare semplicemente il parametro size. –

risposta

11

Questo è perché ajax esegue la richiesta in modo asincrono per impostazione predefinita e prima che il corso di controllo alert(price); la richiesta non ha ancora eseguito e price detiene ancora il vecchio valore.

Se si desidera eseguirlo in modo sincrono, è possibile impostare async su falso.

$.ajax({ 
    async: false, 
    ..... 
    ..... 
}); 
+0

Questo è tutto !!! Naturalmente molto probabilmente nei documenti: -/ –

2

è necessario calcolare all'interno della funzione successo

function calculate_cost(){ 

var price = 0; 
var size = $('form#tshirt_form [name="size"] option:selected').val(); 
$.ajax({ 
    url:'my_script.php', 
    type:'post', 
    data:'query=select price from tshirts.prices where size = "' + size + '"', 
    success:function(data){ 
     if(isjson(data)){ 
      data = $.parseJSON(data); 
      data = data[0]; 
      price = data['price']; 
      // continue code for calculation 
      // this alert will display "0", but I want the price from the database in there 
      alert(price); 
      //perhaps do other ajax calls for other bits of data 
      //... 
     }else{ 
      //display error getting data 
     } 
    } 
}); 

// return final_price; this function wont be able to return a value 
} 
1

ajax è asincrona e per questo motivo si dovrebbe refactoring del codice in modo che si fa ciò che è necessario fare nel callback

$.ajax({ 
    url:'my_script.php', 
    type:'post', 
    data:'query=select price from tshirts.prices where size = "' + size + '"', 
    success:function(data){ 
     if(isjson(data)){ 
      data = $.parseJSON(data); 
      data = data[0]; 
      price = data['price']; 
      //call another function (maybe make another ajax call) from here 
      dosomethingwithprice(price); 
     }else{ 
      //display error getting data 
     } 
    } 
}); 
1

Il codice ajax vuole tempo per l'esecuzione (anche se non molto) ; tuttavia, il codice dopo la chiamata ajax viene eseguito in modo asincrono e molto probabilmente prima che i risultati della chiamata ajax entrino.

Invece, perché non provare a spostare l'avviso (prezzo) nel corpo della regione if(isjson(data)) e quindi eseguire una funzione di richiamata che restituisce il prezzo a qualsiasi altra utilità è necessario per essere utilizzato in?

1

devi eseguire il calcolo all'interno dello stack di richiamata. Ajax funziona in modo asincrono, ovvero i codici estendono la funzione di callback prima dell'esecuzione della funzione di callback. Quindi dovresti fare il tuo calcolo in callback.

function calculate_cost(){ 

    var price = 0; 
    var size = $('form#tshirt_form [name="size"] option:selected').val(); 
    $.ajax({ 
     url:'my_script.php', 
     type:'post', 
     data:'query=select price from tshirts.prices where size = "' + size + '"', 
     success:function(data){ 
      if(isjson(data)){ 
       data = $.parseJSON(data); 
       data = data[0]; 
       price = data['price']; 
      }else{ 
       //display error getting data 
      } 

    // continue code for calculation 
    // this alert will display "0", but I want the price from the database in there 
    alert(price); 
    //perhaps do other ajax calls for other bits of data 
    //... 
     return final_price; 
     } 
    }); 

} 
+0

Sì, lo so che ajax funziona in modo asincrono, è per questo che l'ho aggiunto alla mia domanda. Volevo un modo per fare dove non devo continuare a inserire il mio altro codice all'interno della funzione 'successo'. –

+0

'return final_price;' in realtà non restituirà un valore dalla funzione genitore, che esce semplicemente dal callback ajax. @jeffery_the_wind - La struttura di questo metodo deve essere modificata in modo che calculate_cost() restituisca un oggetto posticipato anziché un valore. –

0

Suggerisco di avere la chiamata ajax restituire un oggetto posticipato. Quindi, quando il prezzo finale viene calcolato completamente, risolvi l'oggetto posticipato con quel valore.

function calculate_cost() { 
    var price = 0, 
     size = $('#tshirt_form [name="size"] option:selected').val(), 
     def = $.Deferred(); 

    $.ajax({ 
     data: {size:size}, 
     url: 'my_script.php', 
     type: 'post', 
     dataType: 'json', 
    }).done(function(data){ 
     data = data[0]; 
     price = data['price']; 
     def.resolve(price); 
    }).fail(function(){ 
     // do on error stuff 
    }); 

    return def.promise(); 
} 
// ... 
calculate_cost("large").done(function(price){ 
    alert(price); 
}).fail(function(){ 
    alert("Failed to retrieve price"); 
});