2016-04-08 9 views
1

Ich habe eine Backbone-Ansicht mit einigen Formularüberprüfung. Die Formularüberprüfung verwendet preventDefault, wenn das Formular Fehler enthält. Wenn dies nicht der Fall ist, sollte der Wert in das Eingabefeld übernommen werden, lat, lng abgerufen und zwei verborgene Felder gefüllt werden, bevor submit fortfahren darf. Ich versuche eine aufgeschobene, aber nicht sicher, was ich falsch verstanden habe. Ich habe hier und da ein paar unnötige Teile herausgeschnitten, um es hier sauberer zu machen.Ausführen und Vervollständigen Google Maps Geocode vor dem Zulassen, um fortzufahren

Ich habe versucht mit preventDefault mit der verzögerten (was ich nicht sowieso korrigieren müssen?), Aber erneut einreichen ist ein bisschen eine Herausforderung mit der Submit-Ereignis.

Ohne preventdefault werden die Felder lat, lng vor dem Senden nicht aktualisiert. Vielleicht eine falsche Implementierung von secreted/promise oder wenn prepatdefault verwendet wird, löst das submit die Validierung erneut aus und ich lande in einer Schleife. Ich möchte setTimeout nicht verwenden, weil ich den Benutzer nicht länger verzögern möchte, als die Antwort zurückzubekommen.

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(); 
}, 

Jede Hilfe oder Hinweise geschätzt!

+0

Ihr Problem ist 'validateForm' nicht Auslösen des Formulars senden? oder etwas anderes? Was macht 'submitCoordinates' hier? –

+0

'submitCoordinates()' oder 'getCoordinates()'? Auch geschweifte Klammern sind aus dem Gleichgewicht geraten. Beheben Sie die Frage, vielleicht kann jemand eine Antwort geben. –

+0

Ich habe den Methodennamen und die Klammer korrigiert. Ohne preventdefault werden die Felder lat, lng vor dem Senden nicht aktualisiert. Vielleicht eine falsche Implementierung von secreted/promise oder wenn prepatdefault verwendet wird, löst das submit die Validierung erneut aus und ich lande in einer Schleife. Ich möchte setTimeout nicht verwenden, weil ich den Benutzer nicht länger verzögern möchte, als die Antwort zurückzubekommen. Danke, –

Antwort

1

Es sieht so aus, als ob Sie aufgrund Ihres inneren parent.submit() wahrscheinlich in eine Endlosschleife geraten. Da parent ein jQuery-Objekt ist, löst es alle Ereignisse erneut aus, wodurch der Ajax unendlich oft erneut ausgelöst wird. Zum Glück ist die Lösung einfach. Rufen Sie für das jQuery-Objekt .submit() auf, rufen Sie es auf dem Formular selbst auf. Sie müssen auch sicherstellen, dass Sie keine id="submit" irgendwo haben. Indem Sie es direkt auf dem Formular aufrufen, senden Sie einfach das Formular, ohne irgendwelche Ereignisse auszulösen.

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 */ 
    }); 
    } 
},