2013-03-30 2 views
0

Я строил пример кода для модуля Twitter Bootstrap Typeahead.Вытягивание внешнего JSON-файла в переменную javascript с помощью jQuery

В ранней версии версии сценария я включил следующее, снятое почти непосредственно из примера, с несколькими настройками, которые отлично работали;

$('.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, написанный на. Я ve создал файл, содержащий только массив следующим образом;

[{"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,' is bad ... и устарело. Переместите код так: «процесс (здания)», 'находится в обратном вызове' 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 doc: http://api.jquery.com/jQuery.getJSON/

Во-вторых, вам нужно ссылаться на переменную данных в соответствии с ее областью (при вызове данных var внутри функции успеха, область изменена и данные var не найдены, это почему он бросает «Не могу прочитать« leangth »undefined»). Вы должны установить собственную ссылочную переменную, которая указывает на область переменных данных.

Это поможет:

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