0

配送料の ajax リクエストに応答して JSON を返す php 関数があります。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 ループに組み込まれています。何か案は?

編集

JSON 文字列をオブジェクトではなくオブジェクトとして使用しようとしていたため、for ループの前に次のコードを追加しました。

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"));

    }

JSON化せずに配列を返しますが、それは意図的なものですか?

さらに、論理エラーがあるようです:

$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));

編集:

この場合、作成したクエリは完全に機能しますが、Codeigniter はクエリの OR 引数を括弧で囲みません。そのため、同じクエリで OR と AND を組み合わせるとバグが発生する可能性があります。コードを書いた方法では、クエリは次のようになります (問題なく動作します)。

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

同じクエリを異なる順序で書くと (または複雑なクエリを書く場合)、非常に異なる結果が得られる可能性があります。

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

いくつかの深刻なバグの後、「or_where」に注意することを学びました:)

于 2012-06-12T18:10:17.520 に答える