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

时间:2013-03-30 15:23:52

标签: javascript jquery json twitter-bootstrap

我一直在构建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;    
},
});

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

  

未捕获的TypeError:无法读取未定义的属性'length'[jquery.min.js:3]

任何想法/想法/尝试解决这个问题的起点都会非常感激!

2 个答案:

答案 0 :(得分:0)

首先,我建议你使用$ .getJSON而不是$ .ajax(你可以节省很多不必要的代码行)。 //在此处查看$ .getJSON doc:http://api.jquery.com/jQuery.getJSON/

其次,您必须根据其范围引用数据变量(在成功函数内部调用数据var时,范围已更改且未找到数据var,这就是为什么它会抛出“无法读取'leangth'的未定义“)。您必须设置一个指向数据变量范围的自引用变量。

这会有所帮助:

$('.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;    
    }
});

答案 1 :(得分:0)

我将对我最后达到的观点进行一些解释,因为这是一个很大的变化;

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

这里是参考代码;

$('.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;
    });
});