在允许提交继续之前执行并完成 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 */
    });
  }
},