使用jQuery将外部JSON文件拉入javascript变量

Pulling external JSON file into a javascript variable using jQuery

本文关键字:javascript 变量 文件 JSON jQuery 外部 使用      更新时间:2023-09-26

我一直在为Twitter Bootstrap Typeahead插件构建一些示例代码。

在脚本的早期开发版本中,我包含了以下内容,几乎直接从示例中提取,并进行了一些完美的自定义;

$('.building_selector').typeahead({
    source: function (query, process) {
        buildings = [];
        map = {};   
        var data = [{"buildingNumber":"1","buildingDescription":"Building One"},{"buildingNumber":"2","buildingDescription":"Building Two"},{"buildingNumber":"3","buildingDescription":"Building Three"}];
        $.each(data, function (i, building) {
            map[building.buildingDescription] = building;
            buildings.push(building.buildingDescription);
        });
        process(buildings);
},
updater: function (item) {
    selectedBuilding = map[item].buildingNumber;
    return item;    
},
});

在实践中,当我将选项数组直接写入代码时,这并没有多大用处,所以我一直在寻找读取写入JSON的外部文件。我已经创建了一个文件,其中只包含如下数组;

[{"buildingNumber":"1","buildingDescription":"Building One"},
{"buildingNumber":"2","buildingDescription":"Building Two"},
{"buildingNumber":"3","buildingDescription":"Building Three"}]

我现在尝试更新Javascript以包含加载远程文件的代码。我可以验证文件是否存在,并且是否在正确的相对位置。

$('.building_selector').typeahead({
    source: function (query, process) {
        buildings = [];
        map = {};
        var data = function () {
            $.ajax({
                'async': false,
                'global': false,
                'url': "../json/buildings",
                'dataType': "json",
                'success': function (result) {
                    data = result;
                }
             });
            return data;
        }(); 
    $.each(data, function (i, building) {
        map[building.buildingDescription] = building;
        buildings.push(building.buildingDescription);
    });
process(buildings);
    },
updater: function (item) {
    selectedBuilding = map[item].buildingNumber;
    return item;    
},
});

在运行页面时,所有元素似乎都按预期工作,并且控制台中没有显示任何内容,直到您在文本字段中单击并键入。每次按下键后,没有任何可见的事情发生,但在控制台中产生以下内容;

Uncaught TypeError: Cannot read property 'length' of undefined [jquery.min.js:3]

任何想法/想法/出发点,试图解决这个问题将是非常感激的!

首先,我建议您使用$。getJSON而不是$。Ajax(可以节省很多不必要的代码行)。//参见$。getJSON文档在这里:http://api.jquery.com/jQuery.getJSON/

第二,你必须根据它的作用域引用数据变量(当在成功函数中调用data var时,作用域已经改变并且没有找到数据变量,这就是为什么它会抛出"Cannot read ' length ' of undefined")。你必须设置一个指向数据变量范围的自引用变量。

这将有助于:

$('.building_selector').typeahead({
    source: function (query, process) {
        var buildings = [];
        var map = {};
        var self = this; //This is a self reference to use in the nested function of $.getJSON
        $.getJSON('../json/buildings', function(data){
            if ($.isArray(data)) {
                $.each(data, function (i, building) {
                    self.map[building.buildingDescription] = building;
                    self.buildings.push(building.buildingDescription);
                });
                process(self.buildings);
            }
        });
    },
    updater: function (item) {
        selectedBuilding = map[item].buildingNumber; // This won't work. I'd suggest to move the map variable as part of the top level object.
        return item;    
    }
});

我将对我最后得出的观点进行一点解释,因为这是一个相当大的变化;

由于JSON文件的内容是动态的,但不需要在每次按键时调用,所以我决定导入它一次,在$document.ready()中使用$.getJSON。然后,它将内容写入一个全局变量,该全局变量可以像以前一样由源函数加载。

这是供参考的代码;

$('.building_selector').typeahead({
    source: function (query, process) {
        buildings = [];
        map = {};   
        $.each(buildinglist, function (i, building) {
            map[building.buildingDescription] = building;
            buildings.push(building.buildingDescription);
        });
        process(buildings);
    },
    updater: function (item) {
        selectedBuilding = map[item].buildingNumber;
        return item;    
    },
});
var buildingList;
$(document).ready(function() {
    $.getJSON('../json/buildings/', function(json){
        buildinglist = json;
    });
});