Felix Riesterer: nicht verzagen!

Beitrag lesen

Lieber RobRobson,

UserLocation_obj.prototype.getLatLngGoogle= function(eventObjekt)
{
this.setAktSuchOrt( $("#suche_ort").val() );
this.setAktSuchOrtLatLng( getUserCoord( this.getAktSuchOrt() ) );
alert( "drausse" + this.getAktSuchOrtLatLng( ) );
}

Du übermittelst hier ein "eventObjekt", machst im späteren Verlauf aber keinen Gebrauch davon. Warum nicht? Welcher Art sollte das Event denn gewesen sein ("click", "mousemove" etc), und wie muss die dazu passende Reaktion sein?

Betrachten wir einmal den Funktionsmechanismus an sich:
    1.) this.setAktSuchOrt(...); // Hier passiert irgendwas.

2.) this.setAktSuchOrtLatLang(getUserCoord(...)); // Hier soll die Funktion
        "getUserCoord" einen Wert zurückliefern, und zwar _sofort_!

3.) alert(...) // Hier soll der von getUserCoord ermittelte Wert
        ausgegeben werden.

Soweit klar? Nun gibt es in getUserCoord aber nur eine Callback-Funktion, deren Aufruf irgendwann einmal stattfinden wird, und der dann erst den gewünschten Wert mitbringen wird. Das passiert wohl über das "geocoder"-Objekt, dessen Methode "geocode" einen Request an Google absetzt, der dann irgendwann beantwortet wird, um dann die gewünschten Geo-Koordinaten zu erhalten.

function getUserCoord( suche_ort ) //Google adapt
{
var myLocLatLng = false;

Hier definierst Du eine lokale Variable mit dem Wert false.

geocoder.geocode( { "address": suche_ort  }, function(results, status) { ... } );

Hier wird der Request vorbereitet, eine Callback-Funktion definiert, und das Ganze abgeschickt.

return myLocLatLng;

Hier hat Deine lokale Variable noch immer false als Wert. Das geocoder-Objekt hat in diesem Moment noch keine Antwort von Google erhalten, die in diese Variable geschrieben werden könnte.

(Das drinnen-alert gibt richtig die gesuchten Koordinaten aus

Logisch, denn es wird dann ausgeführt, wenn von Google eine Antwort kam und somit die Callback-Funktion ausgeführt wurde, in der dieser alert ja steht.

das drausen-alert immer nur false.

Es wird auch vor der Google-Antwort ausgeführt, weil es eben nicht in der Callback-Funktion steht.

Mein Problem ist nach wie vor das eine asyncrone Funktion vorliegt und das ich auf das Ergebniss dieser warten muss.

Nein, Dein Problem ist, dass Du die weitere Verarbeitung Deines Scripts von einer Callback-Funktion erledigen lassen musst, weil Deine Funktion selbst keine Antwort auf Deine Frage ("Geo-Koordinaten?") geben kann.

Wie macht man das? (its all about events?)

Ja, es ist "all about events", indem Du nämlich die Callback-Funktion dahingehend umbauen musst, dass sie Dir die ermittelten Koordinaten in Dein Objekt schreibt. Das tut sie nur auf ein Ereignis hin, nämlich dann, wenn Googles Antwort eingetroffen ist. Die löst nämlich eine Status-Veränderung im XHR-Objekt aus, welches geocoder.geocode() erzeugt hat. Und das auf diese Änderung hin ausgelöste Event ist dasjenige, welches Deine Callback-Funktion (mehrfach!) auslöst. Erst, wenn der Status den passenden Wert hat, reagiert Deine Callback-Funktion überhaupt mit Deinem Code (if-Statement). Ansonsten lässt sie die Statusänderungen uninteressiert über sich ergehen.

Lass mich mal folgendes probieren:

UserLocation_obj.prototype.getLatLngGoogle = function()  
{  
    var t = this; // wird benötigt, damit die Referenz auf unser Objekt  
                  // erhalten bleibt, da sich "this" in der Callback-  
                  // Funktion ändern wird  
  
    t.setAktSuchOrt( $("#suche_ort").val() );  
  
    geocoder.geocode(  
        // Objekt mit Suchdaten  
        {  
            "address": suche_ort  
        },  
  
        // Callback-Funktion  
        function (results, status)  
        {  
            if (status == google.maps.GeocoderStatus.OK)  
            {  
                map.setCenter(results[0].geometry.location);  
                var marker = new google.maps.Marker({  
                    map: map,  
                    position: results[0].geometry.location  
                });  
  
                // Wir haben die Antwort!  
                t.setAktSuchOrtLatLng( // "t" ist noch bekannt (ist eine closure)  
                    results[0].geometry.location.toString()  
                );  
  
                // Daten an den Server posten  
                $.post(  
                    'index.php',  
                     {  
                         // alternativ ginge hier auch results[0].geometry... etc.  
                         geodaten : t.getAktSuchOrtLatLng()  
                     },  
                     function (data) {  
                         $('#resultat').html(data);  
                     }  
                );  
            }  
        }  
    );  
}

Ich habe obigen Code natürlich nicht getestet. Das überlasse ich Dir. Aber Du siehst, wie die Callback-Funktion nun die weitere Verarbeitung übernimmt, ohne dass Du die bisherige Funktion "getUserCoord" noch bräuchtest.

gutn Rutsch und frohes Neues Jahr ;)

Dir auch einen guten Rutsch.

Liebe Grüße,

Felix Riesterer.

--
ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)