Я сделал несколько форм, которые следуют подобному образцу:
два взаимозависимых поля формы, скажем, «адрес улицы» и «местоположение» (lon / lat).
когда пользователь заполняет одно поле, другое обновляется с помощью вызова ajax.
(например, если пользователь заполняет адрес улицы, отправьте запрос в API геокодирования и поместите результат в поле местоположения; если пользователь заполняет местоположение (например, через пользовательский интерфейс карты), сделайте запрос API обратного геокода и поместите результат в поле адреса.
Пока проблем нет, их легко подключить к событиям размытия и / или изменения фокуса.)
Проблема возникает, если форма отправляется до завершения вызова ajax. В этом случае одно поле будет иметь правильное значение, а другое будет устаревшим. Обработчик на сервере должен обнаружить, что это произошло, и обновить устаревшее значение. Мы не можем просто проверить значение по умолчанию, потому что пользователь мог изменить оба поля любое количество раз.
Есть два возможных решения, о которых я подумал, и мне оно не очень нравится. Я хотел бы другие предложения.
Решение 1. Использование скрытых полей в качестве флагов для указания свежести: установите значение по умолчанию на 0, сбросьте его на 0 до отправки запроса ajax и установите на 1, когда ответ возвращается , На стороне сервера проверьте эти поля и заново вычислите любое поле, флаг свежести которого установлен в 0. Здесь все еще есть потенциальное состояние гонки, но окно сильно сужено. Я использовал эту технику, и она работает (например, http://fixcity.org/racks/new/). Это раздражает, поскольку требует больше кода как на клиенте, так и на сервере, и является другим возможным источником ошибок.
Решение 2. Вместо этого используйте синхронные вызовы AJAX ("SJAX"?). Непривлекательный, поскольку AJAX - это просто удобство пользовательского интерфейса, для работы приложения нет необходимости, поэтому я бы предпочел не заставлять вещи чувствовать себя медленно - тогда это становится UI * для * удобства.
Решение 3. Всегда выполняйте постобработку на стороне сервера. Если это дорого, используйте кэширование, чтобы сделать его дешевле, например. если значение не устаревшее, это означает, что клиент только что сделал тот же запрос через AJAX, поэтому мы должны были заполнить кэш, если это необходимо, во время обработчика AJAX.
Этот в настоящее время кажется мне наиболее привлекательным, хотя у него есть два ограничения:
его нельзя использовать для вещей, которые не являются безопасными и идемпотентными, например. если запрос AJAX выполнял POST; и он даже не может быть использован для этого примера, потому что у нас есть два взаимозависимых поля и нет способа узнать, что правильно, а что устарело.