2013-03-30 33 views
0

我一直在构建Twitter引导程序Typeahead插件的一些示例代码。使用jQuery将外部JSON文件拉入JavaScript变量

在脚本的早期开发版本中,我包括了以下内容,几乎直接从示例中解除了一些完美工作的定制;

$('.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]

任何想法/想法/起点来尝试和解决这个问题将不胜感激!

+1

'async':false,'是坏的...并且不推荐使用。将代码移动到'process(buildings);'在'success'回调中。不确定是否可以接受,但如果json文件是静态的,可以将其包含在页面的脚本标记中,并跳过使用AJAX。只需在数组前添加'var myBuildingData =',并在'source'函数中处理该变量 – charlietfl

回答

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; 
    }); 
}); 
0

首先,我会建议您使用$ .getJSON而不是$ .ajax(您可以节省大量不必要的代码行)。 //请参阅$ .getJSON文档:http://api.jquery.com/jQuery.getJSON/

其次,您必须根据其范围引用数据变量(在成功函数内调用data 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;  
    } 
}); 
+0

我一直在试图关注这一点,但无法理解最后的评论。你如何建议使其工作,因为目前没有任何改进! –

+0

我只是建议把地图变量放在building_selector块的外面。 (不要在里面声明)。 – ricardohdz