кэширование на стороне клиента jquery-ui-autocomplete: регулярное выражение javascript / jquery для соответствия строке «index» объекта - PullRequest
0 голосов
/ 03 марта 2012

В моем веб-приложении я использую jquery ui autocomplete , данные которого хранятся в базе данных (Mysql ).
В этом приложении у меня есть официальные данные администрации и , которые позволяют пользователям вводить свои собственные данные. Данные будут отображаться в раскрывающемся списке автозаполнения.
Административные данные 1010 * ограничены и никогда не изменяются, поэтому они предварительно загружаются и кэшируются в памяти, однако пользовательские данные не изменяются (поскольку пользовательские данные растут в геометрической прогрессии и нет смысла использовать базу данных если все кешируется в памяти).

Так что я делаю многоуровневое кэширование в своем веб-приложении, из которого я кеширую пользовательских данных автозаполнения на стороне клиента (вместо того, чтобы получать их из базы данных при каждом поиске).

Сценарий выглядит следующим образом:
Когда приложение загружается, данные администратора (которые предварительно загружены в память) загружаются и кэшируются в объекте JS для использования в механизме автозаполнения.

Таким образом, когда пользователь ищет слово, он проверяет объект JS данных администратора и, если он не может его найти, он переходит в базу данных и находит его в данных пользователя.

Итак для случая поиска данных пользователя в db , то, что я сейчас делаю, таково:

$( "#search" ).autocomplete({
source:function(request, response) {
var results = $.ui.autocomplete.filter(data, request.term);
if (request.term.toUpperCase() in autocomplete_cache) {
    response($.map(autocomplete_cache[request.term.toUpperCase()], function(item) {
     return {value: item.members.name, md5: item.members.ID}
    }))

    return;
   }

, где autocomplete_cache - это объект javascript:

var autocomplete_cache = {};
// ...it gets filled everytime a new $.post gets new data
...autocomplete_cache[request.term.toUpperCase()] = data;

На данный момент он кэширует точный термин , который ищет пользователь .
Например, если пользователь пишет "ABCD" и который еще не кэширован:

-> перейти к базе данных (MySQL) сделать: "ГДЕ термин Like% ABCD%"
-> autocomplete_cache ["ABCD"] = "данные проанализированы из mysql"


Таким образом, если тот же пользователь USER теперь наберет "ABCD" , он получит его из autocomplete_cache Object .
Однако, если тип USER "ABC" , он не получит его из объекта кэша из-за строки:

if (request.term.toUpperCase() in autocomplete_cache)

То, что я хотел бы сделать, это сопоставить то, что пользователь вводит в кэш, поэтому в этом сценарии пользователь вводит "ABC" (который содержится в "ABCD" кэша). String), автозаполнение создаст выпадающий список, содержащий "ABCD" .

Есть ли способ сделать это? Причиной этого требования вместо того, чтобы находить точный индекс String в объекте кеша, он будет находить более широкий диапазон и, таким образом, ограничивать вероятности необходимости обращаться к БД, чтобы найти новые совпадения.

1 Ответ

1 голос
/ 03 марта 2012

Вместо того, чтобы искать конкретный ключ, проверьте каждый ключ, является ли термин подстрокой:

var term = request.term.toUpperCase();
for (var key in autocomplete_cache) {
    if (key.indexOf(term) > -1) {
        // term is contained in key
    }
}

И вместо того, чтобы вызывать response в первом совпадении, собрать все элементы совпадений в дополнительный массив и вызвать response в конце:

var term = request.term.toUpperCase(),
    items = [];
for (var key in autocomplete_cache) {
    if (key.indexOf(term) > -1) {
        items.merge($.map(autocomplete_cache[key], function(item) {
            return {value: item.members.name, md5: item.members.ID}
        });
    }
}
if (items.length > 0) response(items);

Вы также можете удалить все дубликаты в items и отсортировать полученные элементы перед вызовом response:

var term = request.term.toUpperCase(),
    items = [],
    index = {};
for (var key in autocomplete_cache) {
    if (key.indexOf(term) > -1) {
        $.each(autocomplete_cache[key], function(item) {
            var id = item.members.ID;
            if (!index[id]) {
                items.push({value: item.members.name, md5: item.members.ID});
                index[id] = true;
            }
        });
    }
}
items.sort(function(a, b) { return a.name.localeCompare(b.name); });
if (items.length > 0) response(items);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...