Typeahead.js - 搜索多个属性值

26
请参见以下示例。
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>'
    }
});
3个回答

31

Typeahead 0.10.3新增了“支持多属性分词的对象分词器”。

所以,你的示例现在变成了

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

然而,我认为这对于嵌套在内部的属性不起作用,也就是说,在您的情况下,data.category对象不起作用。

另外需要注意的是,如果您正在使用预取数据,请确保先清除本地存储,否则新的令牌化程序将不会生效(因为datumTokenizer在添加到搜索索引时使用,如果数据已经存在于localStorage中,则搜索索引将不会更新)。我曾经被卡住了一段时间!


1
我一直在尝试@timothy的解决方案,但是对我来说并没有起作用。这个解决方案更加优雅且有效。 - TheTechGuy
1
非常好的解决方案,谢谢。顺便说一下,您可以通过 prefetch: { cache: false, ... } 来防止预取缓存。 - Sean Connolly
这是有效的,但警告:您必须按照数据架构中出现的顺序指定属性,否则它将无法正常工作。我认为这是类型提示中的错误,因为对用户来说这是令人惊讶的。 - toddmo

14

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);

7
我已经在这里实现了一个解决方案: 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 - Ben Smith
@Fresh 谢谢您抽出时间来帮忙,这个问题比我最初描述的要稍微复杂一些。我正在使用多个来源(这些来源都有分类标题 - 与 typeahead.js 多源示例 http://twitter.github.io/typeahead.js/examples/ 完全相同)。您能给我一个筛选器用法的例子吗?请注意,我想保留分类标题 (媒体,页面,帖子)。谢谢。 - Iladarsda
我一直在研究filter()方法,但是我想帮助你的建议行不通,即在filter内部构建tokens列表。我认为你应该采用我在答案中提出的解决方案,只是要像你建议的那样添加分类标题。希望你能找到解决方案,我很乐意看到它! - Ben Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接