2012-04-11 5 views
0

数量が増えるにつれて、書籍の価格を生成するためにajaxを使用しています。私が持っている唯一の問題は、合計(JSコードを参照)を生成しようとしたときに、いくつかの問題が発生したことです(値は加算の代わりに連結されます)。私は変数 '量'を四捨五入して問題を解決しました。しかし、私は連結が起こった理由を理解しようとしています。ここに私のPHPコードです:なぜこの値をもう一度丸める必要がありますか?

if(isset($_GET["amount1"])) 
{ 
    $amount1 = $_GET["amount1"]; 

    $error=""; 

    if($amount1 == "" || !preg_match("/^[0-9]+$/", $amount1)) 
    { 
     $error .= "Please enter a valid number"; 
     echo $error; 
    } 
    else{ 
     echo round($amount1*16.65, 2); 
    } 
} 

そして、これは、JSコードです:

 if(xhr.status == 200 && xhr.readyState == 4) 
     { 
     var res = xhr.responseText; 

     if(res.match(/\d+/)== null){ 
      document.getElementById("err3").innerHTML = res; 
      document.getElementById("book3").innerHTML = ""; 
      total(0,3); 
     } 

     else{ 
      document.getElementById("book3").innerHTML = res; 
      document.getElementById("err3").innerHTML = ""; 
      total(res,3); 
      } 
     } 


var book1 = 0; 
var book2 = 0; 
var book3 = 0; 

function total(amount, book) 
{ 
// amount = Math.round(amount*100)/100; --> this is what solved it but I don't  
//know why I need it since amount was rounded by PHP code 
if(book == 1) 
    book1 = amount; 

if(book == 2) 
    book2 = amount; 

if(book == 3) 
    book3 = amount; 

var total = book1 + book2 + book3; 

document.getElementById("total").innerHTML = total; 

} 

おかげ

答えて

4

resがテキストです。使用する前に番号に変換してください。 +オペレータは私が狂わせる文字列の連結と追加して、両方のために使用されているため

js> parseFloat("3.14") 
3.14 
+0

明らかにもっと重要です。簡単なメモのように、 'Number()'を使うと文字列に応じて文字列をintまたはfloatに設定しますが、parse floatはint値に切り捨てられますが、余分なメモリはfloatとして保持されます。 – Anthony

0

それが連結していますという理由があります。しかし、具体的には、入力フィールドに入力された値や、何らかのラッパー(jsonやxml)を使用せずにサーバーからブラウザに渡された値は常にjavascriptによって文字列として扱われ、PHPとは異なり、javascriptは型ジャグリング少なくとも数字と文字列の間にはない)。

これは、Ajaxを経由して戻って、PHPから送信されており、PHPは番号の検証を処理しているので、あなたが本当にちょうどそうのように、JSON形式で値を返し、返されたオブジェクトを使用するにはJavaScriptを更新する必要があるので:

検証に若干の微調整と

まず、PHPは、:

// 1. Using ctype_digit function to confirm value is >= 0. Much faster than regex 
// 2. No need to round, as integer * float is always same or less precision, and 
// PHP sets product to appropriate numeric type. 
// 3. Pushing values into array for json encoding 
// 4. Setting both values (empty if invalid) so that javascript can easily confirm 
// response. 
// 5. Updated Error, as negative numbers and floats are valid, 
// just not in this case 

$amount1 = $_GET["amount1"]); 
$response["amount1"] = (ctype_digit($amount1)) ? $amount1 * 16.65 : ""; 
$response["error"] = (ctype_digit($amount1)) ? "" : "Please enter a valid quantity"; 

echo json_encode($response); 

さて、Javascriptをeval()を使用して、オブジェクトに応答文字列をデシリアライズ、および合計やその他もろもろを取得する必要がありジャ(再び、いくつかのマイナーな改良、メモなしでこの時間)vascript

if(xhr.status == 200 && xhr.readyState == 4) 
{ 
    var res = eval("(" + xhr.responseText + ")"); 

    amount1 = (!isNaN(res.amount1)) ? res.amount1 : "";  

    document.getElementById("err3").innerHTML = res.error; 
    document.getElementById("book3").innerHTML = res.amount1; 
    document.getElementById("total").innerHTML = total(Number(res.amount1),3); 
} 

var book1 = 0; 
var book2 = 0; 
var book3 = 0; 

function total(amount, book) 
{ 
switch (book) { 
    case 1: 
     book1 = amount; 
     break; 
    case 2: 
     book2 = amount; 
     break; 
    case 3: 
     book3 = amount; 
     break; 
} 

return book1 + book2 + book3; 
} 

今、私は最終的にtotal関数にamount1値を渡すとき、あなたはおそらく、私が実際に​​機能に包み気づくことを、どのJSONを使用せずに問題をほぼ解決します。理論的には、PHPが常に数値を返す場合、私はこれを行う必要はありません。ここで私はこれにもかかわらず、Number型にキャスト理由は以下のとおりです。

  1. JSは数の型のジャグリングを行いませんので、これはちょうど良いアイデアです。あなたは、PHPが悪い日に何を返すかを決して知らず、コミュニケーションの両側で検証が行われるべきです。

  2. これによりPHPは値に空の文字列を返すことができ、ユーザに出力することができます。​​は空の文字列を0に設定します。

  3. あなたはAJAXメソッドをスキップして、価格設定計算ブラウザ側を行うことを決定した場合、それが扱ったときに得るための良い(とはいえ迷惑な)習慣ですので、あなたは、常に​​を使用して値をキャストする必要がありますが任意の外部ソースからの数値。

私はちょうどそれを行うまでに感じ、あなたは無視するか、盗むことができ、あなたの全体的な目標に近づくだろうかの最終版では数にjsfiddleを投稿します。

関連する問題