API геолокации — ожидание получения позиции

#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 — координаты в порядке, но пользовательский ввод становится пустым: (Есть идеи?