【问题标题】:data.length is undefined following a successful getJSON operation成功的 getJSON 操作后 data.length 未定义
【发布时间】:2012-03-14 18:02:57
【问题描述】:

我正在使用来自 getJSON 的 JSON 数据填充下拉列表。

填充工作正常,但试图通过与data.length 比较来确定它已完成无法正常工作,因为data.lengthundefined,我不明白为什么!

数据如下:

{
    "1": {
        "id": "1",
        "name": "Plymouth"
    },
    "2": {
        "id": "2",
        "name": "Torquay"
    }
}

我的代码如下:

$('.locationList').empty();
$('.locationList').append('<option value="">Select...</option>');
$.getJSON('/Settings/locations.txt', function (data) {
    var dataNum = data.length;
    var counter = 1;
    $.each(data, function (i, item) {
        $('.locationList').append('<option value="' + data[i].id + '">' + data[i].name + '</option>');
        if (counter >= dataNum) {
            $('#bookTo').val(locationID + 1);
            $('#transferFrom').val(locationID);
        };
        counter++;
    });
});

本节:

if (counter >= dataNum) {
    $('#bookTo').val(locationID + 1);
    $('#transferFrom').val(locationID);
};
counter++;

旨在让我在 $.each 循环完成后预设下拉框的值(这适用于其他列表),但它没有发生。

当我运行alert(data.length) 时,我得到undefined 这毫无意义,因为data 显然确实有一个length,以便它通过$.each 正确填充下拉框,它确实如此!

编辑:抱歉,应该补充一下,变量locationID 是在脚本前面的 Cookie 中声明的,并且是有效的

【问题讨论】:

  • JavaScript object literal length === undefined? 的可能重复项 data 是一个对象,而不是字符串或数组。对象不公开 length 属性。
  • 当你有 jQuery 的 .each() 函数的索引值时,为什么你需要 dataNum 变量?
  • 我需要 dataNum 变量来确定 $.each 何时完成,因为不管文档中说了什么,否则下拉框的值选择会在它完全填充之前发生

标签: jquery json each


【解决方案1】:

当 response.data == [] 时, 这行得通:

if (response.data.length === 0)

这是一个数组,然后有长度。

【讨论】:

    【解决方案2】:

    你的 JSON:

    {"1":{"id":"1","name":"Plymouth"},"2":{"id":"2","name":"Torquay"}}
    

    是一个对象,而不是数组,因此未定义 length 属性。 如果您想将其解析为一个数组,您的服务器需要给出如下响应:

    {"response": [{"1":{"id":"1","name":"Plymouth"}},
    {"2":{"id":"2","name":"Torquay"}}] }
    

    [] 代替{}

    【讨论】:

    • 不对!数组不接受像 json 这样的字符串:{string: value, string: value}。数组是:[value, value]
    • 这不可能是正确的,否则函数的其余部分肯定会失败,对吧?啊...阅读@AndreasAl 的答案与此评论一起为我指明了正确的方向...有点!
    【解决方案3】:

    这可能不是最好的方法,但这样的事情可能是一个快速的解决方案?

    $('.locationList').empty();
    $('.locationList').append('<option value="">Select...</option>');
    $.getJSON('/Settings/locations.txt', function (data) {
        var dataNum = 0;
        for (i in data) {if (data.hasOwnProperty(i)) {dataNum++;}}    
        var counter = 1;
        $.each(data, function (i, item) {
            $('.locationList').append('<option value="' + data[i].id + '">' + data[i].name + '</option>');
            if (counter >= dataNum) {
                $('#bookTo').val(locationID + 1);
                $('#transferFrom').val(locationID);
            };
            counter++;
        });
    });
    

    【讨论】:

    • 是的,我确实这么认为。在这种情况下,它会很好,因为它是一个非常简单的列表,但这不是一个好习惯。
    【解决方案4】:

    这是一个对象:

    data = {
        "1": {
            "id": "1",
            "name": "Plymouth"
        },
        "2": {
            "id": "2",
            "name": "Torquay"
        }
    }
    

    它没有length 属性。

    请参见:仅属性 12

    您确定要将其作为对象评估器然后是数组:

    data = [
        {
            "id": "1",
            "name": "Plymouth"
        },
        {
            "id": "2",
            "name": "Torquay"
        }
    ]
    

    那么您就有了length 属性和许多其他本机数组方法,例如sort。您可以像这样访问您的数据:

    data[0]
    

    女巫等于:

    {
        "id": "1",
        "name": "Plymouth"
    }
    

    【讨论】:

    • :D 我已经更改了locations.txt 的来源,现在可以使用了,谢谢! [{"id":"1","label":"1","name":"Plymouth"},{"id":"2","label":"2","name":"Torquay"}]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 2012-10-31
    • 1970-01-01
    相关资源
    最近更新 更多