我要做的是提交点击事件,我想地理编码并解决和设置表单的值并通过post发送这些值。
在以下代码中,警报用于测试代码的运行顺序。
我需要提醒(" 2")并提醒(" 3")在警告之前处理(" 4" )因此,变量 result1 可以具有一个值,该值将在alert(4)之后由代码使用。现在,代码按此顺序触发(警报按此顺序弹出):1,4,2,3。这里有一个错误:
var testvar = result1.lat();
错误是:
Uncaught TypeError: Cannot read property 'lat' of undefined
这是有道理的,因为#4正在寻找result1变量,然后才能由geocoder1设置(第2点)。它也不会填充表单字段。
$(document).ready(function() {
$("#myForm").submit(function() {
var address = $("#id_user_entered_address").val();
var geocoder = new google.maps.Geocoder();
var result;
alert("point 1");
geocoder.geocode({'address': address1},
function(results, status) {
if(status == google.maps.GeocoderStatus.OK){
result = results[0].geometry.location;
alert("point 2");
}
alert("point 3");
} );
alert("point 4");
var testvar = result.lat();
var testlong = result.lng();
$("#id_latitude").val(testvar);
$("#id_longitude").val(testlong);
alert("point 5");
});
});
也就是说,当我执行以下操作时,我实际上可以使正常工作(但这是一个很大的黑客,因为我不希望人们需要点击两个按钮):
为按钮单击触发的地理编码部分创建单独的函数。
这只留下提交函数中表单变量的设置(在表单的提交按钮上)。我还必须将结果变量更改为全局(不使用var)。
然后我点击提交以激活地理编码功能,当完成后,我点击表单的提交按钮,所有工作都应该如此(即发布数据与表单一起发送)。见如下:
function firstgeocode() {
var address = $("#id_user_entered_address").val();
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': address},
function(results, status) {
if(status == google.maps.GeocoderStatus.OK){
result = results[0].geometry.location;
alert("inside the geocode: " + result);
}
});
};
$(document).ready(function() {
$("#myForm").submit(function() {
var latres = result.lat();
var lonres = result.lng();
$("#id_latitude").val(latres);
$("#id_longitude").val(lonres);
})
});
我不确定究竟是什么问题,因为问题和解决方案似乎是混合:JS中的异步vs同步,回调,闭包和JS中的变量范围。
我尝试过设置回调。下面的脚本实际上正确地进行了地理编码,更改了屏幕上的表单字段,我甚至可以使用和提醒来打印表单元素值,但是后期数据不会随表单一起发送,只有表单的默认值才会在交:
$(document).ready(function() {
$("#myForm").submit(function() {
function geothis(callback){
var address = $("#id_user_entered_address").val();
var geocoder = new google.maps.Geocoder();
alert("point1");
geocoder.geocode({'address': address},
function(results, status) {
if(status == google.maps.GeocoderStatus.OK){
var result = results[0].geometry.location;
alert("inside the geocode: " + result);
callback(result);
}
});
};
function setform(result){
var latres = result.lat();
var lonres = result.lng();
$("#id_latitude").val(latres);
$("#id_longitude").val(lonres);
alert($("#id_longitude").val());
alert("point2");
};
geothis(setform);
});
});
非常感谢任何想法。
答案 0 :(得分:1)
欢迎使用异步编程。您使用回调进入正确的轨道,但在呼叫完成之前,您的代码无法提交。因此,您需要取消表单提交,并在Ajax代码返回后在设置值后提交它。
$("#myForm").submit(function(event) {
event.preventDefault(); //stop the form submission
并在回调中
function setform(result){
var latres = result.lat();
var lonres = result.lng();
$("#id_latitude").val(latres);
$("#id_longitude").val(lonres);
//$("#myForm").off("submit"); //might need to remove the listener
$("#myForm")[0].submit(); //resubmit the form
};
答案 1 :(得分:1)
我看到你在这里使用jQuery所以我建议使用deferred对象。
将函数getGeoLocation包装回来,返回一个promise对象,然后在alert('point3')
点处解析延迟。对于快速代码段,它将是
function getGeoLocation () {
var deferred = new $.Deferred();
geocoder.geocode({'address': address1},
function(results, status) {
if(status == google.maps.GeocoderStatus.OK){
result = results[0].geometry.location;
alert("point 2");
deferred.resolve();
}
alert("point 3");
});
return deferred.promise();
}
然后在行alert('point4')
之后,您可以调用下面的函数,并在.done
延迟时调用resolve
:
getGeoLocation().done(function() {
var testvar = result.lat();
var testlong = result.lng();
$("#id_latitude").val(testvar);
$("#id_longitude").val(testlong);
alert("point 5");
})