在允许提交继续之前执行并完成 google 地图地理编码
Execute and complete google maps geocode before allowing submit to continue
我有一个带有一些表单验证的 backbone 视图。如果表单有错误,表单验证将使用 preventDefault。如果不是,它应该在输入字段中获取值,检索 lat、lng 并在允许继续提交之前填充两个隐藏字段。我正在尝试使用延迟,但不确定我做错了什么。我在这里和那里删掉了一些不必要的部分,使这里的 post 更清晰。
我已经尝试将 preventDefault 与 deferred 一起使用(无论如何我都不应该纠正它?),但是使用提交事件再次提交是一个挑战。
如果没有 preventdefault,lat、lng 字段在提交前不会更新。也许 deferred/promise 的错误实施或使用 preventdefault 时提交再次触发验证,我最终陷入循环。我不想使用 setTimeout,因为我不想让用户延迟比获得响应更长的时间。
events: {
'submit': 'validateForm'
},
validateForm: function(e){
//lotsa validation then
var loc = $('#location').length;
if ( loc ){
var parent = $(e.currentTarget).closest('form');
e.preventDefault();
$.when(this.getCoordinates(e))
.done(function(){
parent.submit();
});
}
},
getCoordinates : function(e) {
var deferred = $.Deferred();
var that = this;
var parent = $(e.currentTarget).closest('form');
var addr = parent.find('#location').val();
if ($.trim(addr).length) {
var apiurl = '//maps.googleapis.com/maps/api/geocode/json?address=' + addr '&bounds=' + bounds + '';
$.ajax({
url : apiurl,
dataType : 'json'
})
.done(function (data) {
try {
if(!data.results.length){
return;
}
var coord = data.results[0].geometry.location;
var result = data.results[0].formatted_address;
if (coord) {
var lat = coord.lat;
var lon = coord.lng;
parent.find("input[data-geo-type = 'lat']").val(lat);
parent.find("input[data-geo-type = 'lng']").val(lon);
deferred.resolve();
}
} catch (e) {
console.error(e);
}
}).fail(function () {
$(e.currentTarget).val(addr);
});
} else {
deferred.reject();
}
return deferred.promise();
},
感谢任何帮助或指点!
由于您的内在 parent.submit()
,您可能 运行 陷入无限循环。由于 parent
是一个 jQuery 对象,它会重新触发所有事件,从而导致 ajax 无限地再次发生。幸运的是,解决方案很简单。不要在 jQuery 对象上调用 .submit()
,而是在表单本身上调用它。您还必须确保在任何地方都没有 id="submit"
。通过直接在表单上调用它,您只需提交表单而不会触发任何事件。
validateForm: function(e){
//lotsa validation then
var loc = $('#location').length;
if ( loc ){
var parent = $(e.currentTarget).closest('form');
e.preventDefault();
$.when(this.getCoordinates(e))
.done(function(){
//parent.submit();
parent[0].submit();/* modified line */
});
}
},
我有一个带有一些表单验证的 backbone 视图。如果表单有错误,表单验证将使用 preventDefault。如果不是,它应该在输入字段中获取值,检索 lat、lng 并在允许继续提交之前填充两个隐藏字段。我正在尝试使用延迟,但不确定我做错了什么。我在这里和那里删掉了一些不必要的部分,使这里的 post 更清晰。
我已经尝试将 preventDefault 与 deferred 一起使用(无论如何我都不应该纠正它?),但是使用提交事件再次提交是一个挑战。
如果没有 preventdefault,lat、lng 字段在提交前不会更新。也许 deferred/promise 的错误实施或使用 preventdefault 时提交再次触发验证,我最终陷入循环。我不想使用 setTimeout,因为我不想让用户延迟比获得响应更长的时间。
events: {
'submit': 'validateForm'
},
validateForm: function(e){
//lotsa validation then
var loc = $('#location').length;
if ( loc ){
var parent = $(e.currentTarget).closest('form');
e.preventDefault();
$.when(this.getCoordinates(e))
.done(function(){
parent.submit();
});
}
},
getCoordinates : function(e) {
var deferred = $.Deferred();
var that = this;
var parent = $(e.currentTarget).closest('form');
var addr = parent.find('#location').val();
if ($.trim(addr).length) {
var apiurl = '//maps.googleapis.com/maps/api/geocode/json?address=' + addr '&bounds=' + bounds + '';
$.ajax({
url : apiurl,
dataType : 'json'
})
.done(function (data) {
try {
if(!data.results.length){
return;
}
var coord = data.results[0].geometry.location;
var result = data.results[0].formatted_address;
if (coord) {
var lat = coord.lat;
var lon = coord.lng;
parent.find("input[data-geo-type = 'lat']").val(lat);
parent.find("input[data-geo-type = 'lng']").val(lon);
deferred.resolve();
}
} catch (e) {
console.error(e);
}
}).fail(function () {
$(e.currentTarget).val(addr);
});
} else {
deferred.reject();
}
return deferred.promise();
},
感谢任何帮助或指点!
由于您的内在 parent.submit()
,您可能 运行 陷入无限循环。由于 parent
是一个 jQuery 对象,它会重新触发所有事件,从而导致 ajax 无限地再次发生。幸运的是,解决方案很简单。不要在 jQuery 对象上调用 .submit()
,而是在表单本身上调用它。您还必须确保在任何地方都没有 id="submit"
。通过直接在表单上调用它,您只需提交表单而不会触发任何事件。
validateForm: function(e){
//lotsa validation then
var loc = $('#location').length;
if ( loc ){
var parent = $(e.currentTarget).closest('form');
e.preventDefault();
$.when(this.getCoordinates(e))
.done(function(){
//parent.submit();
parent[0].submit();/* modified line */
});
}
},