0

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

在运行页面时,所有元素似乎都按预期工作,并且控制台中没有任何内容出现,直到您在文本字段内单击并正在输入。每次按键后,什么都没有发生,但控制台中会产生以下内容;

未捕获的类型错误:无法读取未定义的属性“长度”[jquery.min.js:3]

任何尝试解决此问题的想法/想法/起点将不胜感激!

4

2 回答 2

0

首先,我建议你使用 $.getJSON 而不是 $.ajax(你可以节省很多不必要的代码行)。// 在此处查看 $.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;    
    }
});
于 2013-03-30T23:45:19.023 回答
0

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(). 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;
    });
});
于 2013-04-01T13:42:17.863 回答