如何为 typeahead 数据集中的每个 datumtokenizer 设置唯一的 minLength

How to set unique minLength for each datumtokenizer in typeahead dataset

背景:

我正在使用 typeahead.js 向用户显示搜索建议。我希望用户希望能够看到基于我数据集的 both "title" & "diff" 的建议。我遇到的问题是,当标题和差异字段重叠时,可能会导致一些混乱的结果。

在此图片中,您可以看到活动查询是 "Ea",并且 typehead 正在为标题 "Earthbound" 和差异 "Easy" 提供建议。我不喜欢这个结果,我希望少于 3 个字符的查询只从 "title" 字段中提取。

问题:

如何为数据集中的每个 datumtokenizer 设置唯一的 minLength?因此建议从第一个字符开始的标题中提取,并且建议不会从 "diff" 开始提取,直到查询至少有 3 个字符。

代码:

var games = new Bloodhound({
  datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title', 'diff'),
  queryTokenizer: Bloodhound.tokenizers.whitespace,
  prefetch: 'https://api.myjson.com/bins/ss93y'
);

$('.basic .typeahead').typeahead({
  hint: false,
  highlight: true,
  minLength: 1,
  limit: 5,
}, {
  name: 'games',
  display: 'title',
  source: games,
  templates: {
    header: '<h3 class="games-header">Games</h3>'
  }
});

JS Fiddle: https://jsfiddle.net/n3my5r8u/

鉴于您需要的自定义级别,我建议您实现自己的数据获取和 substringMatcher 函数,而不是使用 Bloodhound。我的解决方案基于 official documentation

中的第一个示例

fetch('https://api.myjson.com/bins/ss93y').then(result => {
  return result.json();
}).then(games => {
  var substringMatcher = (query, cb) => { 
    var normalizedQuery = query.toLowerCase();
    if (normalizedQuery.length < 3) {
      /* if query shorter than 3 chars, filter on title only */
      return cb(games.filter(game => game.title.toLowerCase().includes(normalizedQuery)));
    } else {
      /* if query at least 3 chars, filter on title or diff */
      return cb(games.filter(game => game.title.toLowerCase().includes(normalizedQuery) || game.diff.toLowerCase().includes(normalizedQuery)));
    }
  }

  $('.basic .typeahead').typeahead({
    hint: false,
    highlight: true,
    minLength: 1,
    limit: 50,
  }, {
    name: 'games',
    display: 'title',
    source: substringMatcher,
    templates: {
      header: '<h3 class="games-header">Games</h3>'
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>

<div class="basic">
  <input class="typeahead" type="text" placeholder="Search">
</div>

请注意,我将查询和游戏数据集都转换为小写,因此您的搜索将不区分大小写。