Typeahead.js - 在多个属性值中搜索

Posted

技术标签:

【中文标题】Typeahead.js - 在多个属性值中搜索【英文标题】:Typeahead.js - Search in multiple property values 【发布时间】:2014-03-18 00:36:54 【问题描述】:

请看下面的例子。

JSFiddle:http://jsfiddle.net/R7UvH/2/

如何让typeahead.js (0.10.1) 在多个属性值中搜索匹配项?理想情况下,在整个datadata.titledata.desc 和所有data.category[i].name)内

 datumTokenizer: function(data) 
     // **search in other property values; e.g. data.title & data.desc etc..**
     return Bloodhound.tokenizers.whitespace(data.title);
 ,

整个例子:

var data = [
    title: "some title here",
    desc: "some option here",
    category: [
        name: "category 1",
    , 
        name: "categoy 2",
    ]
,

    title: "some title here",
    desc: "some option here",
    category: [
        name: "category 1",
    , 
        name: "categoy 2",
    ]
];

var posts = new Bloodhound(
    datumTokenizer: function(data) 
        // **search in other property values; e.g. data.title & data.desc etc..**
        return Bloodhound.tokenizers.whitespace(data.title);
    ,
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: data
);
posts.initialize();

$('#search-input').typeahead(
    highlight: true
, 
    name: 'Pages',
    displayKey: 'title',
    source: posts.ttAdapter(),
    templates: 
        header: '<h3>Pages</h3>'
    
);

【问题讨论】:

【参考方案1】:

Typeahead 0.10.3 added "support to object tokenizers for multiple property tokenization."

所以,你的例子变成了

var posts = new Bloodhound(
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title', 'desc'),
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: data
);

但是,我认为这不适用于嵌套在内部的属性,即您的情况下的 data.category 对象。

附带说明,如果你使用的是预取数据,一定要先清除本地存储,否则新的分词器不会生效(因为添加到搜索索引时使用了datumTokenizer,如果数据已存在于localStorage 中,则不会更新搜索索引)。我被困了一段时间!

【讨论】:

几天来一直在研究@timothy 解决方案,但它对我不起作用。此解决方案有效且更优雅。 很好的解决方案,谢谢。旁注,您可以使用 prefetch: cache: false, ... 防止预取缓存 这可行,但请注意:您必须按照属性在数据架构中出现的顺序指定属性;否则,它将无法正常工作。我认为这是预输入中的一个错误,因为它让用户感到惊讶。【参考方案2】:

return Bloodhound.tokenizers.whitespace(data.title) 返回一个字符串数组。

因此,不要返回该值:保存它(以及您需要的其他值),然后将它们连接起来并返回该值...

x = Bloodhound.tokenizers.whitespace(data.title);
y = Bloodhound.tokenizers.whitespace(data.desc);
z = Bloodhound.tokenizers.whitespace(data.category[i].name);
return x.concat(y).concat(z);

【讨论】:

【参考方案3】:

我在这里实现了一个解决方案:

http://jsfiddle.net/Fresh/4nnnG/

由于您拥有本地数据源,因此您需要创建单独的数据集以使您能够匹配多个数据属性。例如

$('#search-input').typeahead(
    highlight: true
, 
    name: 'titles',
    displayKey: 'title',
    source: titles.ttAdapter()
, 
    name: 'descs',
    displayKey: 'desc',
    source: descs.ttAdapter()
, 
    name: 'cats',
    displayKey: 'name',
    source: cats.ttAdapter()
);

【讨论】:

@NullSoulException :D @Fresh 感谢您抽出宝贵时间,它比我最初介绍的要复杂一些。我正在使用多个源(按标题分类 - 与 typeahead.js 多源演示 twitter.github.io/typeahead.js/examples 完全相同)。你能指出一个过滤器使用的例子吗?请注意,我想保留标题(媒体、页面、帖子)的分类。谢谢 我一直在研究 filter() 的方式以及我认为会帮助你的方法不起作用,即在过滤器中建立一个令牌列表。我认为您应该使用我在回答中建议的方式实施解决方案,除非您需要按照您的建议添加分类标题。希望您能找到解决方案,我会很感兴趣地看到它!

以上是关于Typeahead.js - 在多个属性值中搜索的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 5.5 中使用 Typeahead.js 使用两个表格列进行自动完成搜索

如何使用最新的 typeahead.js 库呈现 JSON 响应

Typeahead JS 不适用于具有相同类的多个输入

在 Django 项目中使用 typeahead.js

如何在大型数据库中使用 typeahead.js

Typeahead.js 和 Bloodhound.js 与 C# WebForms WebMethod 的集成