Bloodhound识别bug?

Tac*_*aza 4 typeahead.js twitter-typeahead

我正在使用最新版本的typeahead.js(v0.11.1).当对数据集值使用不同的id时,我观察到了奇怪的行为.

我创建了一个JSFiddle.这是js代码:

var ds = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: [{id: 1, name: "a b 1"}, {id: 2, name: "a b 2"}, {id: 3, name: "a"}],
    identify: function(obj) { return obj.id; }
});

$('#go').typeahead(null, {
    name: 'ds',
    display: 'name',
    source: ds
});
Run Code Online (Sandbox Code Playgroud)

如果我更改"本地"的数据,现在预先输入可能会出现故障.这里只是一些例子:

将这些值中的一个用于'local'(注意第三个元素是以'1'开头的随机数):

[{id:1,name:"ab 1"},{id:2,name:"ab 2"},{id:15,name:"a"}]

[{id:1,name:"ab 1"},{id:2,name:"ab 2"},{id:1849,name:"a"}]

现在,当我进入文本框:"a b"时,预计输入"ab 1"和"ab 2",但事实上它只表示"ab 1".

这可以通过以下方法之一解决:

  • 将第三个元素的'id'属性更改为不以'1'开头的值.例:

    [{id:1,name:"ab 1"},{id:2,name:"ab 2"},{id:23,name:"a"}]

  • 将第三个元素的"name"属性更改为不以"a"开头的值.例:

    [{id:1,name:"ab 1"},{id:2,name:"ab 2"},{id:15,name:"s"}]

  • 删除Bloodhound构造函数对象的'identify'属性.

更重要的是,如果我使用大于2的数字作为第一个元素的id,就像这样:

[{id:3,name:"ab 1"},{id:2,name:"ab 2"},{id:15,name:"a"}]

现在当我在文本框中输入"a b"时,没有任何建议!

Tac*_*aza 5

回答我自己的问题.是的,猎犬有一个错误.SearchIndex.getIntersection()函数未正确实现.您可以取出此功能并像这样测试:

getIntersection([1,2,15],[1,2])
Run Code Online (Sandbox Code Playgroud)

它应该返回[1,2]作为结果,但事实上它返回[1].这是因为它错误地使用sort()函数来排序数字.根据w3schools:

默认情况下,sort()方法按字母顺序和升序将值排序为字符串.

这适用于字符串("Apple"出现在"Banana"之前).但是,如果数字被排序为字符串,则"25"大于"100",因为"2"大于"1".

因此可以通过更改以下两行来修复此功能:

        arrayA = arrayA.sort();
        arrayB = arrayB.sort();
Run Code Online (Sandbox Code Playgroud)

成:

        arrayA = arrayA.sort(function(a, b){return a-b});
        arrayB = arrayB.sort(function(a, b){return a-b});
Run Code Online (Sandbox Code Playgroud)

花了我一天才发现:(