0

我为代码量道歉,但我认为这实际上是 AppMobi 的 getCurrentLocation 函数的问题。基本上发生的事情是我将一个点击事件委托给每个列表元素。然后,当您点击它时,它会运行异步 getCurrentLocation 并更新一些内容。然后下次点击另一个列表元素时,getCurrentLocation函数的回调中绑定的变量仅指第一次调用它。为什么这不起作用?

app = { events: [{text: "foo", time: new Date()}, {text: "bar", time: new Date()}] };
$(document).ready(refreshEvents);

function refreshEvents() {
    for (var index in app.events) {
        insertEventHTML(app.events[index]);
    }
}

function insertEventHTML(event) {
    var text = event.text;
    var time = event.time;

    var new_element = $('<li class="event_element"></li>');
    var new_checkin_element = $('<div class="check_in_button"></div>');

    new_checkin_element.bind('tap', function(e) {
        check_in(e);
        fade($(this), 1.0);
    });
    new_element.append(new_checkin_element);

    var text_element = $('<div class="text_element">' + text + '</div>');
    new_element.append(text_element);
    var time_element = $('<div class="time_element">' + time + '</div>');
    new_element.append(time_element);
    $('#your_events').append(new_element);
}

function check_in(e) {
    $(e.target).siblings('.time_element').text('just now');
    var time = new Date();                   // time and event_index are the trouble variables here
    var event_index = getEventIndex(e);      // the first time this function runs, event_index is correct
                                             // then each subsequent time, it remains the same value as the first
    if (!app.settings.use_location) {
        app.events[event_index].times.unshift({time: time, location: null});
    } else {
        AppMobi.geolocation.getCurrentPosition(onLocationFound, errorFunction);
    }

    function onLocationFound(response) {    
        var lat = response.coords.latitude;
        var lon = response.coords.longitude;
        var last_time = app.events[event_index].times[0];

        if (last_time != undefined && last_time.time == time) {
            // event_index and time here will only ever refer to the first time it was called.  WHY??? 
            add_checkin(response, event_index, time);        
        }else{
            console.log('onLocationFound was called twice');
        }
    }

    function errorFunction(error) {
        $.ui.popup({title: 'geolocation error', message: 'Geolocation error.  Turn off location services in settings.'});
    }

    function add_checkin(response, event_index, time) {
        // and then of course event_index and time are wrong here as well.  I don't get it.
        app.events[event_index].times.unshift(
        {
            time: time, 
            location: {
                latitude: response.coords.latitude,
                longitude: response.coords.longitude
            }
        });
        AppMobi.cache.setCookie('app', JSON.stringify(app), -1);
    }
}

function getEventIndex(e) {
    var target = $(e.target).parent();
    var siblings = target.parent().children('li');
    for (var i = 0; i < siblings.length; i++) {
        if ($(target)[0].offsetTop == $(siblings[i])[0].offsetTop) {
            return i;
        }
    }
}
4

2 回答 2

1

好吧,您的问题似乎是您event_index在函数内部声明了一个私有变量,check_in并尝试通过访问event_index内部的全局变量来解析它的值onLocationFound

您可以这样做:

AppMobi.geolocation.getCurrentPosition(function (response) {
   onLocationFound(response, event_index);
}, errorFunction);

function onLocationFound(response, event_index) { //... }

编辑:

它在 check_in 中声明...

你是对的,不知何故我完全错过了。event_index那么在这种情况下,内部的变量不太可能onLocationFoundcheck_in. 做一个console.log(event_index)里面onLocationFound,它应该是一样的。它可能不同的唯一方法是,如果您在调用处理程序之前修改局部变量,您似乎没有这样做,或者如果getCurrentPosition以某种方式存储第一个处理程序并忽略后续处理程序,但是这个 API 没有任何意义.

编辑2:

由于我们怀疑处理程序可能第二次没有正确注册,我建议这样检查:

function check_in() {
    if (!check_in.called) {
        check_in.called = true;
        check_in.onLocationFound = onLocationFound;
    }

    //...

    function onLocationFound() {
        console.log(arguments.callee === check_in.onLocationFound);
    }
}

您也可以简单地做onLocationFound.version = new Date()并检查arguments.callee.version它是否保持不变。

于 2013-09-10T02:02:19.577 回答
1

我知道您已经将此标记为已回答,但是....它实际上可能不是图书馆的问题。我可以将您引导至@Joel Anair 的帖子,他在该帖子中发布了一篇文章,而第 5 个示例似乎是可能有问题的“问题”;)

JavaScript 闭包是如何工作的?

基本上在 for 循环中,它们都被设置为相同的引用,i所以event_index都将是相同的值/引用。(这就解释了为什么它们都是一样的)。

于 2013-09-10T08:11:10.017 回答