0

我有一个 php 函数,它返回 JSON 以响应 ajax 请求交付费用。这是php函数:

public function getDeliveryOptions($weight, $postcode)
{

    if($weight == 0)
    {

        return array(array("name" => "Non-Deliverable", "value" => "0.00"));

    }

    $this->db->where('dmc_lower_boundary <=', $weight);
    $this->db->where('dmc_upper_boundary >=', $weight);

    if(preg_match("([aA][bB](3[1-8]|4[1-5]|5[1-6])\s?[1-9][a-zA-Z]{2}|[fF][kK](19|20|21)\s?[1-9][a-zA-Z]{2}|[hH][sS][1-9]\s?[1-9][a-zA-Z]{2}|[iI][vV][1-9]{1,2}\s?[1-9][a-zA-Z]{2}|[kK][aA](27|28)\s?[1-9][a-zA-Z]{2}|[kK][wW][1-9]{1,2}?\s?[1-9][a-zA-Z]{2}|[pP][aA][2-8][0-9]\s?[1-9][a-zA-Z]{2}|[pP][hH]([156789]|1[056789]|[2-5][0-9]){1,2}\s?[1-9][a-zA-Z]{2}|[zZ][eE][1-9]\s?[1-9][a-zA-Z]{2})", $postcode))
    {

        $this->db->where("dm_id = ", 1);
        $this->db->or_where("dm_id =", 3);

    }
    elseif(preg_match("/([bB][tT][1-9]{1,2}\s?[1-9][a-zA-Z]{2}|[iI][mM][1-9]{1,2}\s?[1-9][a-zA-Z]{2}|[tT][rR](21|22|23|24|25)\s?[1-9][a-zA-Z]{2})/", $postcode))
    {

        $this->db->where("dm_id =", 1);
        $this->db->or_where("dm_id =", 4);

    }
    elseif(preg_match("/([gG][yY][1-9]\s?[1-9][a-zA-Z]{2}|[jJ][eE][1-4]\s?[1-9][a-zA-Z]{2})/", $postcode))
    {

        $this->db->where("dm_id =", 1);
        $this->db->or_where("dm_id =", 5);

    }
    else
    {

        $this->db->where("dm_id =", 1);
        $this->db->or_where("dm_id =", 2);

    }

    $this->db->group_by("dm_id");
    $query = $this->db->get("delivery_method_option_views");
    //print_r($query->result());
    //print_r(json_encode($query->result()));
    return(json_encode($query->result()));
}

这是我的 javascript(使用原型)将结果发送到服务器并使用响应来创建单选按钮:

function updateDelivery()
{
if($('deliveryUpdate') == null)
{

    return false;

}

// This 'observes' our form submit - sort of like onsubmit
$('deliveryUpdate').observe('submit', function(evt) {

    // Stop the actual event from happening
    evt.stop();

    // This is the url we submit to - change it as needed
    var url = '/checkout/updateDelivery';

    //This will be the form and div we update
    var containerForm = $('deliveryUpdate');
    var optionsDisplay = $('deliveryOptions');

    // Grab all the info in the form
    var form_data = containerForm.serialize();
    var form = containerForm.innerHTML;

    // Here we make the request
    new Ajax.Request(url, {
        method: 'post',
        parameters: form_data,
        onCreate: function() {
            form = containerForm.innerHTML;
            containerForm.update(form+'<img src="/images/loader.gif" alt="loading..." class="loader" />');
        },
        onSuccess: function(transport) {
            containerForm.update(form);
            NVPResponse = transport.responseText;

            if(NVPResponse !== '[object Array]')
            {

                NVPResponse = new Array(NVPResponse);

            }
            alert(NVPResponse);
            options = "";
            for(i=0; i<NVPResponse.length; ++i)

            {

                options += '<label for="delivery">'+NVPResponse[i].dm_name+'</label><input type="radio" name="delivery" value="'+NVPResponse[i].dmc_price+'" />';

            }

            //optionsDisplay.update(NVPResponse);
            optionsDisplay.update(options);
        }

    });

});

}

如果我只是更新 JSON 结果(对于邮政编码 ab31 2as),我会得到以下信息:

Calculate Delivery Costs[{"dm_id":"1","dm_name":"Royal Mail","dm_admin_name":"Royal Mail","dmc_lower_boundary":"101","dmc_upper_boundary":"250","dmc_price":"3.65"},{"dm_id":"3","dm_name":"Courier","dm_admin_name":"Fed Ex Zone 4","dmc_lower_boundary":"101","dmc_upper_boundary":"250","dmc_price":"4.50"}]

但是,如果我使用选项 var 进行更新,我会在标签文本和单选按钮值所在的位置得到“未定义”。这是在 onSuccess 函数的 for 循环中构建的。有任何想法吗?

编辑

我在 for 循环之前添加了以下代码,因为我试图将 JSON 字符串用作对象而不是对象:

NVPResponse = JSON.parse(NVPResponse);
4

1 回答 1

1

我不是原型方面的大专家,但在我看来,你NVPResponse是一个字符串,而不是转换为 javascript 对象。(请参阅AJAX(特别是评估 JavaScript 响应)和JSON的原型文档)。

您的代码似乎还有其他一些问题。

在 PHP 代码中:

if($weight == 0)
    {

        return array(array("name" => "Non-Deliverable", "value" => "0.00"));

    }

你返回一个没有JSONing的数组,这是故意的吗?

此外,似乎还有一个逻辑错误:

$this->db->or_where("dm_id =", 3);

dm_id = 3 的查询,无论您之前设置的任何“位置”如何,因此

$this->db->where('dmc_lower_boundary <=', $weight);
$this->db->where('dmc_upper_boundary >=', $weight);

如果 dm_id = 3(或任何其他 or_where 当然)将被忽略。解决方案可以是这样的:

$this->db->where_in("dm_id", array(1,3));

编辑:

In this case the query you wrote works perfectly well, but you should notice that Codeigniter does not put parentheses around OR arguments in its queries, therefore combining OR and AND in the same query can be buggy. the way you wrote the code the query will look something like this (which works fine):

SELECT * FROM (`t_name`) 
WHERE `dmc_lower_boundary` <= $weight AND `dm_id` = 1 OR `dm_id` = 3

writing the same query in a different order (or sometimes when writing complex queries) can give you a very different result:

SELECT * FROM (`t_name`) 
WHERE `dm_id` = 1 OR `dm_id` = 3 AND `dmc_lower_boundary` <= $weight

after a few serious bugs I learned to be careful with "or_where" :)

于 2012-06-12T18:10:17.520 回答