2

我有以下 JS 方法将 jQuery UI 自动完成小部件绑定到搜索文本框。一切正常,包括缓存,除了我在附加搜索词时进行了不必要的服务器调用,因为我不重用刚刚检索到的结果。

例如,搜索“ab”会从服务器获取一些结果。在搜索框中的“ab”之后键入“c”会从服务器获取“abc”结果,而不是重复使用缓存的“ab”结果并忽略与“abc”不匹配的结果。

我走上了手动查找“ab”搜索结果的路径,使用正则表达式过滤它们以选择“abc”子集,但这似乎完全像是在重新发明轮子。告诉小部件使用“ab”结果,但过滤它们以使用“abc”术语并重新显示缩短的下拉列表的正确、规范的方法是什么?

function bindSearchForm() {
    "use strict";
    var cache = new Object();

    $('#search_text_field').autocomplete({
        minLength: 2,
        source: function (request, response) {
            var term = request.term;
            if (term in cache) {
                response(cache[term]);
                return;
            }
            $.ajax({type: 'POST',
                    dataType: 'json',
                    url: '/get_search_data',
                    data: {q: term},
                    success: function (data) {
                        cache[term] = data;
                        response(data);
                    }
            });
    });
}
4

2 回答 2

2

这是我的“蛮力,重新发明轮子”方法,目前看来,它是正确的解决方案。

function bindSearchForm() {
    "use strict";
    var cache = new Object();
    var terms = new Array();

    function cacheNewTerm(newTerm, results) {
        // maintain a 10-term cache
        if (terms.push(newTerm) > 10) {
            delete cache[terms.shift()];
        }
        cache[newTerm] = results;
    };

    $('#search_text_field').autocomplete({
        minLength: 2,
        source: function (request, response) {
            var term = request.term.toLowerCase();
            if (term in cache) {
                response(cache[term]);
                return;
            } else if (terms.length) {
                var lastTerm = terms[terms.length - 1];
                if (term.substring(0, lastTerm.length) === lastTerm) {
                    var results = new Array();
                    for (var i = 0; i < cache[lastTerm].length; i++) {
                        if (cache[lastTerm][i].label.toLowerCase().indexOf(term) !== -1) {
                            results.push(cache[lastTerm][i]);
                        }
                    }
                    response(results);
                    return;
                }
            }
            $.ajax({type: 'POST',
                    dataType: 'json',
                    url: '/get_search_data',
                    data: {q: term},
                    success: function (data) {
                        cacheNewTerm(term, data);
                        response(data);
                        return;
                    }
            });
    });
}
于 2013-01-03T17:27:53.547 回答
0

如果有人想要一个支持文本框中多个条目的版本,请参见下文:

$(function () {
function split(val) {
    return val.split(/,\s*/);
}

function extractLast(term) {
    return split(term).pop();
}

var cache = new Object();
var terms = new Array();

function cacheNewTerm(newTerm, results) {
    // keep cache of 10 terms
    if (terms.push(newTerm) > 10) {
        delete cache[terms.shift()];
    }
    cache[newTerm] = results;
}

$("#searchTextField")
    .on("keydown",
        function (event) {
            if (event.keyCode === $.ui.keyCode.TAB &&
                $(this).autocomplete("instance").menu.active) {
                event.preventDefault();
            }
        })
    .autocomplete({
        minLength: 2,
        source: function (request, response) {
            var term = extractLast(request.term.toLowerCase());
            if (term in cache) {
                response(cache[term]);
                return;
            } else if (terms.length) {
                var lastTerm = terms[terms.length - 1];
                console.log('LAst Term: ' + lastTerm);
                if (term.substring(0, lastTerm.length) === lastTerm) {
                    var results = new Array();
                    for (var i = 0; i < cache[lastTerm].length; i++) {
                        console.log('Total cache[lastTerm[.length] = ' +
                            cache[lastTerm].length +
                            '....' +
                            i +
                            '-' +
                            lastTerm[i]);
                        console.log('Label-' + cache[lastTerm][i]);
                        var cachedItem = cache[lastTerm][i];
                        if (cachedItem != null) {
                            if (cachedItem.toLowerCase().indexOf(term) !== -1) {
                                results.push(cache[lastTerm][i]);
                            }
                        }
                    }
                    response(results);
                    return;
                }
            }

            $.ajax({
                url: '@Url.Action("GetSearchData", "Home")',
                dataType: "json",
                contentType: 'application/json, charset=utf-8',
                data: {
                    term: extractLast(request.term)
                },
                success: function (data) {
                    cacheNewTerm(term, data);
                    response($.map(data,
                        function (item) {
                            return {
                                label: item
                            };
                        }));
                },
                error: function (xhr, status, error) {
                    alert(error);
                }
            });
        },
        search: function () {
            var term = extractLast(this.value);
            if (term.length < 2) {
                return false;
            }
        },
        focus: function () {
            return false;
        },
        select: function (event, ui) {
            var terms = split(this.value);
            terms.pop();
            terms.push(ui.item.value);
            terms.push("");
            this.value = terms.join(", ");
            return false;
        }
    });
于 2017-10-31T15:37:43.577 回答