【问题标题】:Autocomplete sometimes doesn't show results from server自动完成有时不显示来自服务器的结果
【发布时间】:2016-08-22 18:13:55
【问题描述】:

代码解释如下。

这是我正在使用的自动完成功能(但我检查了其他 3 个自动完成包,它们的行为方式都相同):

https://goodies.pixabay.com/javascript/auto-complete/demo.html

这是我在客户端使用它的方式(请注意,我将自动完成功能与 socket.io 结合使用,以便在用户在搜索框中键入内容时更新我的​​自动完成功能) :

socket.on('searchBarResults', function(data) {

var my_autoComplete = new autoComplete({
    selector: 'input[name="searchbar4"]',
    minChars: 1,
    cache: false,
    source: function(term, suggest){
        term = term.toLowerCase();
        var choices = [
            data[0]._source.movie
        ];
        var matches = [];
        for (i=0; i<choices.length; i++)
            if (~choices[i].toLowerCase().indexOf(term)) matches.push(choices[i]);
        suggest(matches);
    }
});

    $searchBar4.on('input', function(event){
        my_autoComplete.destroy();
    });
});

这就是这一切所做的:当用户开始输入电影的名称时,在他们输入的每个单词之后,服务器都会在数据库中搜索匹配项,并将结果发送给客户端。

例如:如果用户搜索Star,服务器会发回Star Trek Undiscovered Country,并且搜索框会显示自动完成选项 称为星际迷航未知国

这一切都很好。

如果用户键入 Star Trek,服务器将再次发送回 Star Trek Undiscovered Country,并且自动完成功能将更新。没关系。

这是我遇到的问题:

如果用户输入Star Country,服务器发回Star Trek Undiscovered Country,但自动完成 不会显示它。

仅当单词按顺序(您不能跳过单词)时,自动完成才会显示结果。

无论用户在搜索框中输入单词的顺序如何,我如何才能让自动完成功能始终显示来自服务器的结果?

【问题讨论】:

    标签: jquery autocomplete


    【解决方案1】:

    问题出在你的:

    if (~choices[i].toLowerCase().indexOf(term)) matches.push(choices[i]);
    

    它将删除所有与该术语不匹配的项目。

    "Star Trek Undiscovered Country".toLowerCase().indexOf("Star Country")

    它将返回 -1,因为它不包含整个字符串。您需要将其拆分为单词并逐个进行比较。

    你应该可以做这样的事情:

    var match = function(term, suggest){
            term = term.toLowerCase();
    
            // for debugging.
            var choices = new Array();
            choices.push('Star Trek Undiscovered Country');
    
            var matches = [];
            for (i=0; i<choices.length; i++)
            {
                var allMatches = true;
                var words = term.split(' '); // Split into words and check them individually.
    
                //TODO: Possibly handle case when there is only one word.
    
                for(var y = 0; y<words.length; y++)
                {
                    // Check if this word is in choices[i].
                    if (choices[i].toLowerCase().indexOf(words[y]) == -1)
                    {
                        // Not a match.
                        allMatches = false;
                        // Possibly continue when allMatches == false, since the following words doesn't matter.
                    }
                }
                if(allMatches)
                {
                    matches.push(choices[i]);
                }
            }
            suggest(matches);
        }
    
    var suggest = function(item){
      console.log(item);
    };
    match('Star Country', suggest); // Returns one item.
    match('Star Blaster', suggest); // Returns no items.

    另外,choices 似乎总是一个包含 1 个项目的数组?为什么要用数组呢?

    【讨论】:

    • 它似乎不起作用。具体来说,关于indexOf(word) == -1,它说的是(word) 的使用:可能对意外(自定义/继承)成员进行迭代,可能缺少 hasOwnPropery...
    • 好的,我将indexOf(word) == -1 更改为indexOf(word) == 0,它最初似乎可以正常工作。如果我输入 Star Country,我现在会得到完整的 Star Trek Undiscovered Country 结果。我将做更多的测试并稍后确认。
    • 是的,这是错误的。我已经使用有效的 sn-p 更新了代码。
    • @MonkeyOnARock - 不要使用 indexOf(word) == 0,因为它会检查它是否是字符串中的第一个单词。请改用带有适当 for 循环的更新示例。
    • 感谢您提供更多信息。至于您的整体解决方案,它运行良好。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-19
    • 1970-01-01
    • 2013-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多