Добрый день, коллеги!
В одном из проектов мне потребовалось сохранять выбранные пользователем настройки (сделанные в виде чекбоксов). Поскольку предполагалось, что настройки будут изменяться нечасто — я решил передавать настройки не все сразу, а в виде последовательности изменений. Детали реализации под катом.
Начну с постановки задачи. Есть объект, представляющий из себя набор контактной информации. Пользователь выбирает, в каком виде его сохранять, после чего на сервере происходит преобразование объекта в нужный вид. Но пользователь может захотеть сохранять не всю информацию, а только интересующую его часть. Для этого ему нужно предоставить выбор — что сохранять.
Можно сохранять просто асинхронными AJAX-запросами, но в этом случае может возникнуть не очень приятная ситуация, когда очередное изменение отправилось на сервер — и где-то по дороге застряло, а пользователь уже пытается сохранить контакт. В результате он получит не совсем то, что ожидал. Возникает вопрос — как сделать, чтобы изменения сохранялись строго по порядку. Для этого я решил воспользоваться имеющимися в jQuery очередями.
Очереди в jQuery применяются для реализации анимации и эффектов, но никто не мешает использовать их просто для последовательного выполнения нужных действий. В результате у меня получился примерно такой код:
При переключении чекбокса в очередь ставится новый шаг — функция отправки изменения на сервер. Если при этом очередь была пустая, то функция тут же запускается на выполнение (dequeue в функции ajaxQueue). После выполнения имеющегося в функции AJAX-запроса из очереди извлекается очередной шаг и выполняется.
Запрос на сохранение контакта точно так же ставится в очередь и выполняется после того, как все изменения отработали.
PS: В процессе написания этой статьи я пришел к мысли, что все-таки проще передавать все состояния чекбоксов оптом перед сохранением контакта (это к вопросу о том, почему полезно писать статьи :) ), но возможно описанная мной схема кому-нибудь пригодится для других задач.
В одном из проектов мне потребовалось сохранять выбранные пользователем настройки (сделанные в виде чекбоксов). Поскольку предполагалось, что настройки будут изменяться нечасто — я решил передавать настройки не все сразу, а в виде последовательности изменений. Детали реализации под катом.
Начну с постановки задачи. Есть объект, представляющий из себя набор контактной информации. Пользователь выбирает, в каком виде его сохранять, после чего на сервере происходит преобразование объекта в нужный вид. Но пользователь может захотеть сохранять не всю информацию, а только интересующую его часть. Для этого ему нужно предоставить выбор — что сохранять.
Можно сохранять просто асинхронными AJAX-запросами, но в этом случае может возникнуть не очень приятная ситуация, когда очередное изменение отправилось на сервер — и где-то по дороге застряло, а пользователь уже пытается сохранить контакт. В результате он получит не совсем то, что ожидал. Возникает вопрос — как сделать, чтобы изменения сохранялись строго по порядку. Для этого я решил воспользоваться имеющимися в jQuery очередями.
Очереди в jQuery применяются для реализации анимации и эффектов, но никто не мешает использовать их просто для последовательного выполнения нужных действий. В результате у меня получился примерно такой код:
function ajaxQueue(func){ $(document).queue("ajax",func); if($(document).queue("ajax").length == 1) $(document).dequeue("ajax"); } $(".contact input:checkbox") .change(function(){ var $_ = $(this), checked = $_.is(":checked"), $_.attr("disabled","disabled"); ajaxQueue(function(){ $.post("/ajax/check_elem", {name: $_.attr("id"), value: checked}) .error(function(){ $_.val((!checked)?"on":"off"); }) .complete(function() { $_.removeAttr("disabled"); $(document).dequeue("ajax"); }); }); });
При переключении чекбокса в очередь ставится новый шаг — функция отправки изменения на сервер. Если при этом очередь была пустая, то функция тут же запускается на выполнение (dequeue в функции ajaxQueue). После выполнения имеющегося в функции AJAX-запроса из очереди извлекается очередной шаг и выполняется.
Запрос на сохранение контакта точно так же ставится в очередь и выполняется после того, как все изменения отработали.
function doAction(link){ $.get(link, function(data){ $('body').append(data); }, 'html'); } $("a.saveButton") .click(function(){ ajaxQueue(doAction($(this).attr("href"))); });
PS: В процессе написания этой статьи я пришел к мысли, что все-таки проще передавать все состояния чекбоксов оптом перед сохранением контакта (это к вопросу о том, почему полезно писать статьи :) ), но возможно описанная мной схема кому-нибудь пригодится для других задач.