Как передать переменные из библиотеки в контроллер в Appcelerator/Titanium?

Я пытаюсь поместить функцию геолокации (получение широты и долготы) в библиотеку и вернуть широту и долготу, потому что координаты вызываются во всем приложении. Я могу вызвать гео-библиотеку из controller.js, широта и долгота отображаются в консоли, но как я могу использовать координаты в вызывающей функции из controller.js?

в приложении/lib/geo.js

exports.getLongLat = function checkLocation(){
if (Ti.Geolocation.locationServicesEnabled) {
    Titanium.Geolocation.getCurrentPosition(function(e) {
        if (e.error) {
            Ti.API.error('Error: ' + e.error);
            } else {
                Ti.API.info(e.coords);
                var latitude = e.coords.latitude;
                var longitude = e.coords.longitude;
                console.log("lat: " + latitude + " long: " + longitude);
            }
        });
    } else {
        console.log('location not enabled');
}

};

контроллер.js

geolocation.getLongLat(); //this calls the library, but I don't know how I can get the coordinates "back" into the controller.js file for using it in the var args below.

var args ="?display_id=check_if_in_dp_mobile&args[0]=" + lat + "," + lon;

person user24957    schedule 16.07.2017    source источник


Ответы (1)


Создание многоразовой библиотеки для этого — отличная идея, и вы на правильном пути. Проблема с getCurrentPosition заключается в том, что является асинхронным, поэтому мы должны получить данные из него немного по-другому.

Обратите внимание, что в geo.js в строке Titanium.Geolocation.getCurrentPosition(function(e) {... есть функция, передаваемая в getCurrentPosition. Это функция обратного вызова, которая выполняется после того, как телефон получил данные о местоположении. Это связано с тем, что getCurrentPosition является асинхронным, а это означает, что код в этой функции обратного вызова не будет выполняться до более позднего момента времени. У меня есть несколько заметок об асинхронных обратных вызовах здесь.

С вашей функцией getLongLat главное, что нам нужно сделать, это передать ей обратный вызов, который, в свою очередь, может быть передан в getCurrentPosition. Что-то вроде этого:

exports.getLongLat = function checkLocation(callback){
    if (Ti.Geolocation.locationServicesEnabled) {
        //we are passing the callback argument that was sent from getLongLat
        Titanium.Geolocation.getCurrentPosition(callback);
    } else {
        console.log('location not enabled');
    }
};

Затем, когда вы выполняете функцию, вы передаете ей обратный вызов:

//we moved our callback function here to the controller where we call getLongLat
geolocation.getLongLat(function (e) {
    if (e.error) {
        Ti.API.error('Error: ' + e.error);
    } else {
        Ti.API.info(e.coords);
        var latitude = e.coords.latitude;
        var longitude = e.coords.longitude;
        console.log("lat: " + latitude + " long: " + longitude);
    }
}); 

В этом случае мы в основном перемещаем содержимое этой функции, первоначально переданной в getCurrentPosition, туда, где вы вызываете getLongLat в своем контроллере. Теперь вы сможете что-то делать с данными координат при выполнении обратного вызова.

Еще одно место, где обратные вызовы возникают в приложениях Titanium, — это выполнение сетевых запросов с помощью Ti.Network.HttpClient. Вот аналогичный пример того, что вы пытаетесь сделать, создав библиотеку для ваших запросов геолокации только с запросами HTTPClient.

person Adam Paxton    schedule 16.07.2017
comment
Большое спасибо Адам за четкое объяснение. Особенно часть, в основном перемещающая содержимое этого.... это была последняя недостающая часть, которую я не получил. - person user24957; 16.07.2017