#javascript #yii #geolocation
#javascript #yii #геолокация
Вопрос:
Мне просто интересно, как правильно использовать API геолокации для следующего варианта использования:
У меня есть веб-сайт (предназначенный для мобильных телефонов) с некоторой формой. Пользователь вводит некоторый текст и нажимает «Отправить». Мне нужно записать местоположение пользователя (координаты GPS) вместе с введенными данными и (важно!) выдать предупреждающее сообщение, если пользователь не дал разрешения или мы не смогли определить его ее местоположение.
С моей точки зрения, проблема в том, что API геолокации является асинхронным. Таким образом, после нажатия кнопки «Отправить» поток выполнения отделяется от основного потока, действующего как обычно после отправки — записи данных в базу данных, а обратный вызов асинхронного потока выполняется только тогда, когда API получает координаты.
На данный момент я реализовал некоторое обходное решение — добавлена пользовательская функция getLocation JS для выполнения onSubmit:
function recordPosition(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
//perform POST query to the server to write coordinates to the database
}
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(recordPosition);
} else {
alert("Geolocation is not supported by this browser.");
}
}
Но этот подход разделяет запись данных и запись местоположения, и я не могу запретить сохранение данных без позиции..
Как только я новичок в асинхронной работе, я хотел бы просто иметь синхронизированную версию функции getCurrentPosition, но это кажется невозможным идеологически неправильным решением. Но что мне тогда делать в этом случае?
Ответ №1:
Посмотрите этот пример здесь: https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition
В принципе, если вы выполняете свой пост с помощью JavaScript — у вас нет проблем.
Вы можете сделать что-то вроде:
HTML:
JS:
function onSubmit(){
var iLat = document.getElementById('latitude');
if(!iLat.value){
getLocation();
return false;
}
}
function recordPosition(position) {
var iLat = document.getElementById('latitude');
var iLong = document.getElementById('longitude');
iLat.value = position.coords.latitude;
iLong.value = position.coords.longitude;
iLat.form.submit();
}
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(getLocation_success, getLocation_error);
} else {
alert("Geolocation is not supported by this browser.");
}
}
function getLocation_success(pos){
showPosition(pos);
recordPosition(pos);
}
function getLocation_error(err){
console.warn('ERROR(' err.code '): ' err.message);
}
Комментарии:
1. Конечно, я прочитал это руководство. Но, похоже, вы не уловили проблему (потому что ваш пример в основном такой же, как я написал в начале) — у меня есть форма с данными, И я хочу иметь координаты И связать их с данными из формы. Я не хочу их разделять, мне нужно, чтобы они были соединены друг с другом.
2. Я думаю, что вы, возможно, полностью упустили мою точку зрения. Вы не должны пытаться публиковать дважды. ознакомьтесь с моим обновленным ответом, который блокирует первое сообщение, затем ожидает позиции и снова публикует.
3. Да, обновленная версия лучше, несколько часов назад я реализовал тот же подход. Это именно то, что мне было нужно, спасибо. Было бы здорово, если бы вы добавили JSFiddle к своему ответу просто в качестве иллюстрации. Но на самом деле я столкнулся с другой проблемой (может быть, специфичной для Yii для CActiveForm?) — когда я это делаю, значение ввода текста теряется, событие, если я предупреждаю об этом только в функции onSubmit — координаты в порядке, но пользовательский ввод становится пустым: (Есть идеи?