我为代码量道歉,但我认为这实际上是AppMobi的getCurrentLocation函数的一个问题。基本上发生的是我将tap事件委托给每个列表元素。然后当你点击它时,它运行一个异步的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;
}
}
}
答案 0 :(得分:1)
好吧,您的问题似乎是您在event_index
函数中声明了一个私有变量check_in
,并尝试通过访问{{1}内的全局event_index
变量来解析它的值}}
以下是您可以做的事情:
onLocationFound
编辑:
它在check_in ...
中声明
你是对的,我完全错过了。那么在这种情况下,AppMobi.geolocation.getCurrentPosition(function (response) {
onLocationFound(response, event_index);
}, errorFunction);
function onLocationFound(response, event_index) { //... }
内的event_index
变量与onLocationFound
中的check_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
以查看它是否保持不变。
答案 1 :(得分:1)
我知道你已经标记了这个已经回答但是....它可能实际上不是库的问题。我可以将你引导到@Joel Anair的帖子,在那里他发表了一篇文章,第五个例子似乎是可能有问题的“问题”;)
How do JavaScript closures work?
基本上在for循环中,它们都被设置为i
的相同引用,因此event_index
将是相同的值/引用。 (这解释了为什么他们都是一样的)。