使用AJAX源的Bootstrap Typeahead:不按预期返回数组

我在使用AJAX源正确使用bootstraps typeahead时遇到了很多麻烦。

如果我提醒正在返回的数组,那就完全没问题了,即使我对它进行硬编码测试也是如此。 当您输入近似匹配时,它似乎大部分时间都没有返回任何内容,或者只返回数组中的一些项目。

这就是我现在所拥有的:

$('#companyNameInput').typeahead({ source: function(query, process){ $.ajax({ url: ROOT+'Record/checkCompanyName', async: false, data: 'q='+query, type: 'POST', cache: false, success: function(data) { companiesFinal = []; map = {}; companies = $.parseJSON(data); $.each(companies, function(i, v){ map[v.name] = v.id; companiesFinal.push(v.name); }) } }) process(companiesFinal); // return ['test1', 'test2'] This works fine return companiesFinal; } 

有谁知道为什么这个工作正常?


这是从我的PHP脚本返回的对象数组的示例。 ID为1和1216的对象显示在typeahead下拉列表中,但不显示其他对象。 我看不出任何模式或线索,为什么只有这些才会显示而不是其他。

 [   {      "id": "1265",      "score": "40",      "name": "LMV AB"   },   {      "id": "10834",      "score": "33",      "name": "Letona"   },   {      "id": "19401",      "score": "33",      "name": "Lewmar"   },   {      "id": "7158",      "score": "33",      "name": "Lazersan"   },   {      "id": "3364",      "score": "33",      "name": "Linpac"   },   {      "id": "1216",      "score": "33",      "name": "LH Evans Limted"   },   {      "id": "1",      "score": "33",      "name": "LH Evans Ltd"   },   {      "id": "7157",      "score": "33",      "name": "Lazersan"   } ] 

最后是process(companiesFinal)的数组process(companiesFinal)

 ["LMV AB", "Letona", "Lewmar", "Lazersan", "Linpac", "LH Evans Limted", "LH Evans Ltd", "Lazersan"] 

有人有任何线索吗? 我仍然完全无能为力,为什么这仍然没有工作:(


 $('#companyNameInput').typeahead({ source: function(query, process){ companyTOut = setTimeout(function(){ return $.ajax({ url: ROOT+'Record/checkCompanyName', data: 'q='+query, type: 'POST', dataType: 'json', cache: false, success: function(data) { var count = 0; var companiesFinal = []; map = []; $.each(data, function(i, v){ map[v.name] = [v.id, v.score]; companiesFinal.push(v.name); }) process(companiesFinal); } }) }, 250) }, minLength: 2, highlighter: function(item) { $('#companyNameInput').closest('.control-group').removeClass('success') companyLocked = false; return ''+item+''; }, updater: function(item) { selectedEntityId = map[item][0]; selectedCountryScore = map[item][1]; lockCompany(selectedEntityId); return item; } }); 

 $output .= '['.$output; foreach($results as $result) { $output .= '{"id":"'.$result['id'].'",'; $output .= '"score":"'.$result['score'].'",'; $output .= '"name":'.json_encode($result['name']).'},'; } header('Content-Type: application/json'); echo substr($output, 0, strlen($output)-1).']'; 

“parm”的控制台输出:

 [Object, Object, Object, Object, Object, Object] 0: Object id: "25024" name: "part" score: "75" __proto__: Object 1: Object id: "15693" name: "pari" score: "75" __proto__: Object 2: Object id: "28079" name: "Pato" score: "50" __proto__: Object 3: Object id: "18001" name: "PASS" score: "50" __proto__: Object 4: Object id: "15095" name: "PSR" score: "33" __proto__: Object 5: Object id: "22662" name: "PRP" score: "33" __proto__: Object length: 6 __proto__: Array[0] 

更新2

啊,您的服务返回实际与查询parm不匹配的项目。 您的先行查询是'parm' ,返回的结果都不匹配。 您可以覆盖typeahead插件使用的matcherfunction,请参阅文档 。 只需将其实现为return true即可匹配您的服务返回的所有结果。

更新1

这是一个更新版本,它将名称映射到id,稍后可以使用。 一个jsfiddle是可用的 。

 var nameIdMap = {}; $('#lookup').typeahead({ source: function (query, process) { return $.ajax({ dataType: "json", url: lookupUrl, data: getAjaxRequestData(), type: 'POST', success: function (json) { process(getOptionsFromJson(json)); } }); }, minLength: 1, updater: function (item) { console.log('selected id'+nameIdMap[item]); return item; } }); function getOptionsFromJson(json) { $.each(json, function (i, v) { nameIdMap[v.name] = v.id; }); return $.map(json, function (n, i) { return n.name; }); } 

原始答案

您需要调用异步调用并从成功回调中调用process回调,如下所示:

 $('#companyNameInput').typeahead({ source: function (query, process) { $.ajax({ url: ROOT + 'Record/checkCompanyName', // async: false, // better go async data: 'q=' + query, type: 'POST', cache: false, success: function (data) { var companiesFinal = ... // snip process(companiesFinal); } }) } }); 

return ['test1', 'test2']; 有效,因为源函数基本上设置为:

 // do ajax stuff, but do nothing with the result // return the typeahead array, which the typeahead will accept as the result: return ['test1', 'test2']; 

笔记

有一个单行填补companiesData

 var companiesFinal = return $.map(data, function (n, i) { n.name; }); 

你可能想用var声明你的变量; 否则他们将拥有全球范围,这将咬你。