我一直在构建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]
任何想法/想法/尝试解决这个问题的起点都会非常感激!
答案 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;
});
});