Typeahead - 无法使用动态创建的数组作为数据源
Typeahead - Unable to use dynamically created array as source of data
我有一个 json
文件,其中包含国家和每个国家的城市,结构如下:
{
"United States": [
"New York",
"Los Angeles",
"San Francisco",
"Baltimore",
"Washington"
],
"England": [
"Manchester",
"Liverpool",
"Newcastle",
"Bradford",
"London"
]
}
在页面加载时,我提取国家并将它们推入 array
。在 select 国家/地区,我根据 selected 国家/地区创建了 array
个城市。该代码适用于预定义的 array
,但不适用于新创建的代码。有什么想法吗?
Jsfiddle here。
HTML:
<div id="countryContainer">
<label>Heroes from country:</label>
<select multiple="multiple" data-placeholder="Select a country" id="countryList"></select>
</div>
<br><br>
<input type="text" id="search">
JS代码有点长:
$(document).ready(function () {
var source = [];
$.ajax({
url: "https://api.myjson.com/bins/22mnl",
dataType: "json",
success: function (response) {
response1 = response;
var keys = Object.keys(response);
keys.forEach(function (key) {
source.push(key);
});
console.log(source);
for (var i = 0; i < source.length; i++) {
var option1 = $('<option value=' + source[i] + '>' + source[i] + '</option>');
$("#countryList").append(option1);
}
}
});
});
$('#countryList').select2();
var citiesArray = [];
var citiesObjArr = [];
//creation of array of countries from the json
$("#countryList").on("change", function () {
if ($("#countryContainer li").length > 1) {
console.log("changed");
var selectedCountry = $("#countryList option:selected")[0].innerHTML;
console.log("country selected: " + selectedCountry);
citiesObjArr.length = 0;
citiesArray.length = 0;
createArrayOfCities(selectedCountry);
} else {
console.log("empty");
}
});
//extraction of cities per selected country from the original json and insertion into an array of objects
function createArrayOfCities(key) {
$.ajax({
url: "https://api.myjson.com/bins/22mnl",
dataType: "json",
success: function (response) {
if (response.hasOwnProperty(key)) {
var j = 0;
var i = 0;
response[key].forEach(function (i) {
citiesArray[j] = i;
//CREATION OF THE CITIES OBJECTS ARRAY
citiesObjArr.push({
val: i
});
j++;
});
}
console.log(citiesObjArr);
console.log(typeof (citiesObjArr));
}
});
}
//typeahead autocomplete here
//THIS ARRAY OF OBJECTS WORK, BUT citiesObjArr DOES NOT. WHY??
/*
var data1 = [{
val: "city1111"
}, {
val: "city2222",
}];
*/
var titles = new Bloodhound({
datumTokenizer: function (data) {
return Bloodhound.tokenizers.whitespace(data.val);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: citiesObjArr
});
titles.initialize();
$("#search").typeahead({
highlight: true
}, {
name: 'titles',
displayKey: 'val',
source: titles.ttAdapter()
});
这里的问题是您在成功回调之外失去了对 citiesObjArr
的访问权限。要解决此问题,您可以 defer 您的响应对象:
在您的 change
处理程序中,您可以执行以下操作:
$.when(createArrayOfCities())
.then(function(data) {
// Pass in the response and selected country to a new function
handleResponse(data, selectedCountry);
});
您需要将 createArrayOfCities()
函数更改为以下内容:
function createArrayOfCities() {
return $.ajax({
url: "https://api.myjson.com/bins/22mnl",
dataType: "json",
success: function (response) {
return response;
}
});
}
注意:您可能需要更改上述函数的名称以提高可读性(因为它不再构建城市数组)
然后你可以调用新的handleResponse
函数:
function handleResponse(response, key) {
if (response.hasOwnProperty(key)) {
var j = 0;
var i = 0;
response[key].forEach(function (i) {
citiesArray[j] = i;
////CREATION OF THE CITIES OBJECTS ARRAY
citiesObjArr.push({
val: i
});
j++;
});
};
var titles = new Bloodhound({
datumTokenizer: function (data) {
return Bloodhound.tokenizers.whitespace(data.val);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: citiesObjArr
});
titles.initialize();
$("#search").typeahead({
highlight: true
}, {
name: 'titles',
displayKey: 'val',
source: titles.ttAdapter()
});
}
我有一个 json
文件,其中包含国家和每个国家的城市,结构如下:
{
"United States": [
"New York",
"Los Angeles",
"San Francisco",
"Baltimore",
"Washington"
],
"England": [
"Manchester",
"Liverpool",
"Newcastle",
"Bradford",
"London"
]
}
在页面加载时,我提取国家并将它们推入 array
。在 select 国家/地区,我根据 selected 国家/地区创建了 array
个城市。该代码适用于预定义的 array
,但不适用于新创建的代码。有什么想法吗?
Jsfiddle here。
HTML:
<div id="countryContainer">
<label>Heroes from country:</label>
<select multiple="multiple" data-placeholder="Select a country" id="countryList"></select>
</div>
<br><br>
<input type="text" id="search">
JS代码有点长:
$(document).ready(function () {
var source = [];
$.ajax({
url: "https://api.myjson.com/bins/22mnl",
dataType: "json",
success: function (response) {
response1 = response;
var keys = Object.keys(response);
keys.forEach(function (key) {
source.push(key);
});
console.log(source);
for (var i = 0; i < source.length; i++) {
var option1 = $('<option value=' + source[i] + '>' + source[i] + '</option>');
$("#countryList").append(option1);
}
}
});
});
$('#countryList').select2();
var citiesArray = [];
var citiesObjArr = [];
//creation of array of countries from the json
$("#countryList").on("change", function () {
if ($("#countryContainer li").length > 1) {
console.log("changed");
var selectedCountry = $("#countryList option:selected")[0].innerHTML;
console.log("country selected: " + selectedCountry);
citiesObjArr.length = 0;
citiesArray.length = 0;
createArrayOfCities(selectedCountry);
} else {
console.log("empty");
}
});
//extraction of cities per selected country from the original json and insertion into an array of objects
function createArrayOfCities(key) {
$.ajax({
url: "https://api.myjson.com/bins/22mnl",
dataType: "json",
success: function (response) {
if (response.hasOwnProperty(key)) {
var j = 0;
var i = 0;
response[key].forEach(function (i) {
citiesArray[j] = i;
//CREATION OF THE CITIES OBJECTS ARRAY
citiesObjArr.push({
val: i
});
j++;
});
}
console.log(citiesObjArr);
console.log(typeof (citiesObjArr));
}
});
}
//typeahead autocomplete here
//THIS ARRAY OF OBJECTS WORK, BUT citiesObjArr DOES NOT. WHY??
/*
var data1 = [{
val: "city1111"
}, {
val: "city2222",
}];
*/
var titles = new Bloodhound({
datumTokenizer: function (data) {
return Bloodhound.tokenizers.whitespace(data.val);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: citiesObjArr
});
titles.initialize();
$("#search").typeahead({
highlight: true
}, {
name: 'titles',
displayKey: 'val',
source: titles.ttAdapter()
});
这里的问题是您在成功回调之外失去了对 citiesObjArr
的访问权限。要解决此问题,您可以 defer 您的响应对象:
在您的 change
处理程序中,您可以执行以下操作:
$.when(createArrayOfCities())
.then(function(data) {
// Pass in the response and selected country to a new function
handleResponse(data, selectedCountry);
});
您需要将 createArrayOfCities()
函数更改为以下内容:
function createArrayOfCities() {
return $.ajax({
url: "https://api.myjson.com/bins/22mnl",
dataType: "json",
success: function (response) {
return response;
}
});
}
注意:您可能需要更改上述函数的名称以提高可读性(因为它不再构建城市数组)
然后你可以调用新的handleResponse
函数:
function handleResponse(response, key) {
if (response.hasOwnProperty(key)) {
var j = 0;
var i = 0;
response[key].forEach(function (i) {
citiesArray[j] = i;
////CREATION OF THE CITIES OBJECTS ARRAY
citiesObjArr.push({
val: i
});
j++;
});
};
var titles = new Bloodhound({
datumTokenizer: function (data) {
return Bloodhound.tokenizers.whitespace(data.val);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: citiesObjArr
});
titles.initialize();
$("#search").typeahead({
highlight: true
}, {
name: 'titles',
displayKey: 'val',
source: titles.ttAdapter()
});
}