简体   繁体   English

使用jQuery将外部JSON文件提取到javascript变量中

[英]Pulling external JSON file into a javascript variable using jQuery

I've been building onto some example code for the Twitter Bootstrap Typeahead plugin. 我一直在为Twitter Bootstrap Typeahead插件构建一些示例代码。

In an early development version of the script, I included the following, lifted almost directly from the example, with a few customisations that have worked perfectly; 在该脚本的早期开发版本中,我包括以下内容,这些内容几乎直接从该示例中提炼出来,其中一些自定义效果很好。

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

In practice, this isn't much use while I've got the array of options written directly into the code, so I've been looking at reading an external file with the JSON written in. I've created a file, containing just the array as follows; 在实践中,当我直接将选项数组写入代码时,这没什么用,所以我一直在看用写入的JSON读取外部文件。我创建了一个文件,其中仅包含数组如下;

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

And I've now attempted to update the Javascript to include the code to load up the remote file. 现在,我已经尝试更新Javascript,使其包含用于加载远程文件的代码。 I can verify the file exists and is in the correct relative location. 我可以确认文件存在并且位于正确的相对位置。

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

On running the page, all of the elements appear to work as expected, and nothing appears in the Console, until you click inside the text field and being typing. 在运行页面时,所有元素似乎都可以正常工作,并且在控制台中什么也没有出现,直到您在文本字段中单击并进行键入为止。 After each keypress, nothing visibly happens, but the following is produced in the Console; 每次按键后,没有明显的反应,但是控制台中将产生以下内容;

Uncaught TypeError: Cannot read property 'length' of undefined [jquery.min.js:3] 未捕获的TypeError:无法读取未定义的属性“ length” [jquery.min.js:3]

Any ideas/thoughts/starting points to try and fix this would be much appreciated! 任何想法/想法/起点来尝试解决此问题将不胜感激!

First of all, I would recommend you to use $.getJSON instead of $.ajax (you can save a lot of unnecessary lines of code). 首先,我建议您使用$ .getJSON而不是$ .ajax(您可以节省很多不必要的代码行)。 // See $.getJSON doc here: http://api.jquery.com/jQuery.getJSON/ //在此处查看$ .getJSON文档: http ://api.jquery.com/jQuery.getJSON/

Second, you have to reference the data variable according to its scope (when calling data var inside the success function, the scope has changed and the data var is not found, that is why it's throwing "Cannot read 'leangth' of undefined"). 其次,您必须根据其范围引用数据变量(当在成功函数中调用数据变量时,范围已更改并且未找到数据变量,这就是为什么它抛出“无法读取未定义的'长度')”的原因。 You have to set a self reference variable that points to the data variable scope. 您必须设置一个自引用变量,该变量指向数据变量范围。

This will help: 这将有助于:

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

I shall add a little explaination of the point I reached in the end, as it's quite a change; 我将对我最后要达到的观点进行一些解释,因为这是一个很大的变化。

As the content of the JSON file is dynamic, but doesn't need to be called on every keypress, I decided to import it once, using $.getJSON inside a $document.ready() . 由于JSON文件的内容是动态的,但是不需要在每次按键时都调用,因此我决定在$document.ready()使用$.getJSON一次导入一次。 It then writes the content into a global variable, which can be loaded by the source function exactly as before. 然后,它将内容写入全局变量,该源变量可以像以前一样完全由源函数加载。

Here's the code for reference; 这是参考代码;

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM