使用 'remote' 时,Typeahead 和 Bloodhound 会显示不相关的建议

Typeahead and Bloodhound shows unrelated suggestions when 'remote' is used

当使用带有远程选项的 Typeahead/Bloodhound 时,当 local/prefetch 结果在 "limit" 下时 (5) 显示的建议与输入无关。看起来它只是从结果的顶部显示设置为 5。

图片:'Love'为预期结果,其他一切无关:

我的代码:

    var keywords = [
 {"value": "Ambient"}, {"value": "Blues"},{"value":  "Cinematic"},{"value":  "Classical"},{"value": "Country"},
 {"value": "Electronic"},{"value": "Holiday"},{"value": "Jazz"},{"value": "Lounge"},{"value": "Folk"},
  {"value": "Hip Hop"},{"value": "Indie"},{"value": "Pop"},{"value": "Post Rock"},{"value": "Rock"},{"value": "Singer-Songwriter"},{"value": "Soul"},
  {"value": "World"},{"value": "Happy"},{"value": "Sad"},{"value": "Love"},{"value": "Angry"},
  {"value":"Joy"},{"value": "Delight"},{"value": "Light"},{"value": "Dark"},{"value": "Religious"},{"value": "Driving"},
  {"value":"Excited"},{"value": "Yummy"},{"value": "Delicious"},{"value": "Fun"},{"value": "Rage"},
  {"value":"Hard"},{"value": "Soft"}
  ];


// Instantiate the Bloodhound suggestion engine
var keywordsEngine = new Bloodhound({
    datumTokenizer: function (datum) {
        return Bloodhound.tokenizers.whitespace(datum.value);
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: keywords,
    remote: {
        url: '/stub/keywords.json',
        filter: function (keywords) {
            // Map the remote source JSON array to a JavaScript object array
            return $.map(keywords, function (keyword) {
                return {
                    value: keyword.value
                };
            });
        }
    },
    prefetch: {
        url: '/stub/keywords.json',
        filter: function (keywords) {
            // Map the remote source JSON array to a JavaScript object array
            return $.map(keywords, function (keyword) {
                return {
                    value: keyword.value
                };
            });
        }
    }
});

// kicks off the loading/processing of `local` and `prefetch`
keywordsEngine.initialize();

$('#keyword-search-input').typeahead({
  hint: true,
  highlight: true,
  minLength: 1
},
{
  name: 'keyword',
  displayKey: 'value',
  // `ttAdapter` wraps the suggestion engine in an adapter that
  // is compatible with the typeahead jQuery plugin
  source: keywordsEngine.ttAdapter()
});

经过进一步研究,我认为我需要手动过滤远程建议,根据 Github Issues for Typeahead.js 上的这个帖子:

"So the idea is I guess that the data returned from remote should already be filtered by the remote, so no further filtering is done on that."

https://github.com/twitter/typeahead.js/issues/148

我希望更深入地讨论这个问题以供将来参考。请记住,我不是 JavaScript 专家或任何这方面的专家。对于 Bloodhound 引擎,它不适应与 remote url 的搜索参数的持续动态交互。因此,如果您正在使用某些 json 文件,则预输入搜索框将仅显示 limit。因此,如果 limit: 10 则显示 json 数据的前 10 条记录,并且即使用户键入,结果也不会改变。只有 json 的第一条记录会有基于用户提示的建议,这是微不足道的。

但是,如果 remote 源有一个 query(例如触发查询)获得所需的结果 as in this example,则搜索框每次都会填充相关结果搜索框已填充。

那么,如果您有一个很大的 json 文件,它是从某个数据库生成的,而不是使用 prefecth 怎么办?显然,为了速度和效率,您需要使用 remote。使用 php 脚本,您需要执行以下操作:

$key=$_GET['key'];
$con=mysqli_connect("localhost","root","");
$db=mysqli_select_db($con, "database_name");
$query=mysqli_query($con, "SELECT * FROM table WHERE column LIKE '%{$key}%'");
$rows=array();
while($row=mysqli_fetch_assoc($query))
{
  $rows[] = $row; 
}
echo json_encode($rows);        

在这里,您使用 GET 获取搜索参数的值,并且您已经与数据库建立了连接,因此您的搜索池将始终根据用户提示使用 "relevant results" 进行补充。