2014-07-18 2 views
0

Мне было интересно, как получить автозаполнение, работающее в моем тестовом приложении. Я разрабатываю Laravel 4, просто для практики. Поэтому я просто нашел его в google и нашел this library, а jQuery - единственная его зависимость.Как правильно обрабатывать запрос ajax

Я не эксперт по JavaScript и jQuery, и я ничего не знаю о AJAX, я просто сделал то, что в руководстве сказал и с некоторым здравым смыслом понял, как он работает в целом.

Вот код JavaScript, который применяет операцию автозавершения:

$('#autocomplete').autocomplete({ 
    serviceUrl: '/search', 
    onSelect: function(suggestion) { 
     $('#autocomplete-suggestions').html("<a href='users/" + suggestion.data + "'>" + suggestion.value + "</a>"); 
    } 
}) 

Я определил услуги в файле routes.php, так как это очень мало:

Route::get('search', function() { 
    $users = User::all(); 
    $response = array(
     "suggestions" => array() 
    ); 
    foreach ($users as $user) { 
     array_push($response["suggestions"], array("value" => $user->username, "data" => $user->id)); 
    } 

    return Response::json($response); 
}); 

Как это работает у меня интересно. Я имею в виду, что каждый раз, когда пользователь вводит символ в поле ввода, выполняется запрос и выполняется служба, которая находится в методе маршрутов. Это подразумевает извлечение всех пользователей из базы данных, хранение их в массиве и последующее копирование их снова в новый массив, чтобы он соответствовал ожидаемому вводу. И затем, на этом json фактический поиск сделан.

Это кажется мне очень неэффективным, поскольку эта операция имеет стоимость и выполняется с большой частотой. Было бы лучше, если бы поиск был выполнен как запрос к базе данных, а не объект-объект для нескольких копий (потенциально) большого количества данных.

Кроме того, я высеваю несколько новых пользователей с этой частью коды:

for ($i = 0; $i<1000; $i++) { 
    $user = new User; 
    $user->username = 'username' . $i; 
    // assign the rest of the attributes 
    $user->save(); 
} 

И казалось, что поиск не был сделан правильно. Я думаю, это другая проблема, касающаяся самой библиотеки автозаполнения.

Итак, поскольку я не знаком с AJAX, я просто хочу знать, является ли это обычным способом работы, или если это действительно ужасная идея, как я думаю. Каким будет правильный способ сделать это?

+0

Я думаю, что вы правы. Ваш обработчик маршрута поиска должен фильтровать пользователей на основе предложения и возвращать только рекомендуемых пользователей. То, как вы его построили сейчас, неэффективно, и я был бы удивлен, если бы он фактически фильтровал. Обычно для каждого изменения делается новый запрос. – GolezTrol

+0

Что сказал @GolezTrol, с дополнительным комментарием, который вы можете (и, возможно, должны) кэшировать результаты. Это «облегчит нагрузку» на сервере, так как он может проверять кеш для результатов поиска, а не ударять по базе данных снова и снова. – Kryten

ответ

1

Должен ли я возвращать всех пользователей с каждым запросом и выполнять поиск на стороне клиента?

Абсолютно нет. Когда запрос отправляется на ваш сервер через AJAX, поисковый запрос предоставляется в виде параметра строки запроса. Из их документы:

Веб-страница, которая предоставляет данные для Ajax автозаполнения, в нашем случае autocomplete.ashx получит запрос GET с запросом строки запроса = Li, и он должен возвращать данные в формате JSON в следующем формате

Вы можете получить, что с Laravel: $query = \Input::get('query');

Вы должны использовать эту строку для поиска на вашем users таблицу, используя красноречив или любой другой и вернуться только соответствующие предложения.

Ужасно ли делать HTTP-запрос с каждым нажатием клавиши?

Эта библиотека имеет опцию deferRequestBy. Когда задано целочисленное значение (миллисекунды), оно будет долго ждать до выполнения запроса на событие keyUp.Если произойдет другое событие keyUp, оно отменяет первый. Это помогает сократить количество одновременных запросов, которые вы можете запустить.

https://github.com/devbridge/jQuery-Autocomplete/blob/master/src/jquery.autocomplete.js#L384-L384

непосредственно из Readme on Github:

deferRequestBy: Количество милисекунд отложить АЯКС запрос. Значение по умолчанию: 0.

Так, чтобы ответить на ваш вопрос:

Так, так как я не знаком с AJAX, я просто хочу знать, если это обычный способ работать, или если действительно страшная идея, как я думаю, . Каким будет правильный способ сделать это?

Да, если вы используете значение по умолчанию 0, это, вероятно, ужасная идея. Но этого не должно быть.

Другие из вашего вопроса:

  1. Вы действительно должны пойти к БД и получить все пользователей каждый раз. Как насчет кеширования?
+0

Хороший комментарий, но на самом деле он не отвечает на вопрос. – GolezTrol

+0

Отличный вопрос об использовании кеша. Просто используя '$ users = DB :: table ('users') -> запомнить (10) -> get();' вместе с deferRequestBy сделают хорошее решение. Просто нужно будет искать коллекцию для правильного пользователя и возвращать это. – user3158900

+0

@ GolezTrol Есть несколько точек, которые он поднял, я пытался ответить на них. –

Смежные вопросы