0

我需要能够在选择框中选择一个国家,然后获取该国家的所有州。

我正在尝试做这样的事情:how-to-display-json-data-in-a-select-box-using-jquery

这是我的控制器:

foreach($this->settings_model->get_state_list() as $state)
{
   echo json_encode(array($state->CODSTA, $state->STANAM));
}

和我的 javascript:

 $.ajax({
    url: 'settings/express_locale',
    type: 'POST',
    data: { code: location, type: typeLoc },
    success: function (data) {
        console.log(data);
    }
});

console.log 向我展示了这样的内容:

["71","SomeState0"]["72","SomeState"]["73","SomeState2"]["74","SomeState3"]

所以,我需要将所有状态附加到一个新的选择框中。

但我试图在成功回调中读取这个数组:

$.each(data, function(key,val){
   console.log(val);
});

结果,每一行都是一个单词,如下所示:

[
 "
 7
 1
 "
 ,
 "
 s
 ....
 ]

为什么会发生这种情况,我错过了什么?

4

3 回答 3

5

JSON 不是由独立的块组成的。所以这永远不会:

foreach($this->settings_model->get_state_list() as $state)
{
    echo json_encode(array($state->CODSTA, $state->STANAM));
}

输出将被视为text,迭代器将循环对象的元素......这是单个字符

您需要声明一个列表或字典。我已经包含了一些示例,具体取决于您在 jQuery 回调中使用数据的方式。注意:PHP 方面,您可能还需要为 JSON 输出正确的 MIME 类型:

$states = array();
foreach($this->settings_model->get_state_list() as $state)
{
    // Option 1: { "71": "SomeState0", "72": "Somestate2", ... }
    // Simple dictionary, and the easiest way IMHO
    $states[$state->CODSTA] = $state->STANAM;

    // Option 2: [ [ "71", "SomeState0" ], [ "72", "SomeState2" ], ... ]
    // List of tuples (well, actually 2-lists)
    // $states[] = array($state->CODSTA, $state->STANAM);

    // Option 3: [ { "71": "SomeState0" }, { "72": "SomeState2" }, ... ]
    // List of dictionaries
    // $states[] = array($state->CODSTA => $state->STANAM);
}

Header('Content-Type: application/json');
// "die" to be sure we're not outputting anything afterwards
die(json_encode($states));

在 jQuery 回调中,您可以使用 charset 指定数据类型和内容类型(这将在您遇到像奥兰群岛这样的状态时派上用场,其中服务器以 ISO-8859-15 发送数据并且浏览器运行页面在 UTF8 中可能会导致痛苦的 WTF 时刻):

        $.ajax({
            url: 'settings/express_locale',
            type: 'POST',
            data: { code: location, type: typeLoc },
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (data) {
                $("#comboId").get(0).options.length = 0;
                $("#comboId").get(0).options[0] = new Option("-- State --", "");
                // This expects data in "option 1" format, a dictionary.
                $.each(data, function (codsta, stanam){
                   n = $("#comboId").get(0).options.length;
                   $("#comboId").get(0).options[n] = new Option(codsta, stanam);
             });
           },
           error: function () {
                alert("Something went wrong");
           }
于 2012-10-17T20:54:49.973 回答
0

您是否尝试过使用 $.map() 代替?

http://api.jquery.com/jQuery.map/

$.map(data, function(index, item) {
console.log(item)
})
于 2012-10-17T20:54:36.853 回答
0

您应该使用 GET 而不是 POST,因为您实际上并没有创建任何新的服务器端。阅读一些关于REST以及为什么使用 GET 是这里的专有名词。

我添加了一个 JSFiddle 示例,您可以立即运行。 http://jsfiddle.net/KJMae/26/

如果这是 PHP 服务返回的 JSON:

{
    "success":true,
    "states":[
        {
            "id":71,
            "name":"California"
        },
        {
            "id":72,
            "name":"Oregon"
        }
    ]
}

这是我们的 HTML 代码:

<select id="country">
    <option value="">No country selected</option>
    <option value="1">USA</option>
</select>

<select id="states">
</select>​

这是将其添加到选择的代码可能如下所示:

// Bind change function to the select
jQuery(document).ready(function() {
    jQuery("#country").change(onCountryChange);
});

function onCountryChange()
{
    var countryId = jQuery(this).val();    

     $.ajax({
        url: '/echo/json/',
        type: 'get',
        data: {
            countryId: countryId
        },
        success: onStatesRecieveSuccess,
        error: onStatesRecieveError
    });
}

function onStatesRecieveSuccess(data)
{
    // Target select that we add the states to
    var jSelect = jQuery("#states");

    // Clear old states
    jSelect.children().remove();

    // Add new states
    jQuery(data.states).each(function(){        
        jSelect.append('<option value="'+this.id+'">'+this.name+'</option>');
    });
}

function onStatesRecieveError(data)
{
    alert("Could not get states. Select the country again.");
}​

至于 PHP,这里有一个简单的例子,它应该给出与上面例子中使用的 JSON 相同的结果。(还没有测试过,从我的头顶来看,这里没有 php。)

$result = new stdClass;
$result->states = array();

foreach($this->settings_model->get_state_list() as $state)
{
    $stateDto = new stdClass();
    $stateDto->id = $state->CODSTA;
    $stateDto->name = $state->STANAM;

    $result->states[] = $stateDto;
}

$result->success = true;

die(json_encode($result));
于 2012-10-17T21:56:23.217 回答