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

2 回答 2

4

res是文本。使用前将其转换为数字。

js> parseFloat("3.14")
3.14
于 2012-04-11T01:39:12.820 回答
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(),并获取总数和诸如此类:

javascript(再次,一些小的调整,这次没有注释)

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;
}

现在,您可能会注意到,当我最终将 amount1 值传递给total函数时,我实际上将其包装在Number()函数中,这几乎解决了不使用 JSON 的问题。理论上,我不需要这样做,如果 PHP 总是返回一个数值。尽管如此,我还是将其转换为 Number 类型的原因如下:

  1. 因为 js 不对数字进行类型处理,所以这只是一个好主意。你永远不知道 PHP 在糟糕的一天会返回什么,并且验证应该在通信的两端进行。

  2. 这允许 PHP 为该值返回一个空字符串,您可以将其输出给用户,然后Number()将空字符串设置0为 total 函数。

  3. 如果您决定跳过 ajax 方法并在浏览器端进行定价计算,则必须始终使用 转换值Number(),因此在处理来自任何外部来源的数值时,这是一个好习惯(尽管很烦人) .

我将在几篇文章中发布一个 jsfiddle,其中包含我将如何实现您的总体目标的最终版本,您可以忽略或窃取,我只是觉得可以这样做。

于 2012-04-11T04:49:27.040 回答