Michael: Schleife will nicht (mehr)

Hallo zusammen!

Ich bin ein neuling was die Programmierung in JS angeht. Ich habe vor einigen Jahren man C angeschaut das ist aber auch alles.
Nun muss / will ich mit GoogleMaps Koordinaten markieren. Das geht auch alles soweit, die API ist ja recht gut!
ABER:
Ich habe eine Schleife. DIese Schleife durchläuft eine XML-Datei und darin alle <markers> Tags.
Aber es funkt nicht mehr so wirklich. Es sind 3 Einträge in dieser XML-Datei. Ich wähle mit "x" immer mit bei welchem Eintrag ich gerade bin.
Nun aber folgendes eigenartiges verhalten das ich nicht recht verstehe:
Der Index, sprich "x" ist immer "2", auch beim ersten Durchlauf!
Die Koordinaten werden richtig ermittelt. DIe zusatzdaten aus der XML-Datei nimmt er aber immer (weil x ja immer 2 ist) aus dem letzten EIntrag.

Was übersehe ich oder verstehe ich falsch?

LG und danke
MIchael

[Code]
    GDownloadUrl("datax.xml", function(data) {
          var xml = GXml.parse(data);
          var markers = xml.documentElement.getElementsByTagName("marker");
          for (var x = 0; x < markers.length; x++) {
            var latlng = new GLatLng(parseFloat(markers[x].getAttribute("lat")),
                                    parseFloat(markers[x].getAttribute("lng")));
   var tooltext = markers[x].getAttribute("tooltext")
   var imageURL =markers[x].getAttribute("image")
   var adresse =markers[x].getAttribute("adresse")

geocoder.getLatLng(adresse,
      function(point) {
        if (!point) {
          alert(address + " not found");
        } else {
          map.setCenter(point, 13);
    map.addOverlay(createMarker(point, x, adresse,imageURL));

} });

//map.addOverlay(createMarker(latlng, i, tooltext,imageURL));
          }
       });
[code]

  1. Ich habe eine Schleife. DIese Schleife durchläuft eine XML-Datei und darin alle <markers> Tags.

    Ich wähle mit "x" immer mit bei welchem Eintrag ich gerade bin.

    Der Index, sprich "x" ist immer "2", auch beim ersten Durchlauf!

    (Bitte sorge doch dafür, dass der Code beim nächsten Mal sauber formatiert im Forum ankommt. Es gibt hier eine Vorschau-Funktion und die saubere Formatierung erhöht die Lesbarkeit und damit die Antwortwahrscheinlichkeit ungemein.)

    for (var x = 0; x < markers.length; x++) {

    geocoder.getLatLng(adresse,
         function(point) {

    map.addOverlay(createMarker(point, x, adresse,imageURL));

    }
       );

    //map.addOverlay(createMarker(latlng, i, tooltext,imageURL));

    }

    Dein Problem dürfte sein, dass du in getLatLng() eine Funktion definierst (function(point))und versuchst, in dieser Funktion auf eine Variable zuzugreifen, die gewissermaßen nur außerhalb der Funktion existiert, nämlich x.

    Wenn du mal genau hinschaust, wirst du sehen, dass der Unterschied zu der von dir auskommentierten, vermutlich funktionierenden Vorversion ist, dass dort die Zählvariable i, anders als x, nicht in einer Funktionsdefinition steckt.

    Ich weiß nicht, welchen Zweck die Funktion geocoder.getLatLng() erfüllen soll, wann ihr Funktionsparameter aufgerufen wird und woher der Parameter point kommt. Überlege dir, ob die Möglichkeit besteht, an der Quelle von point oder in adresse den Inhalt von x abzulegen (den Inhalt, nicht x selbst), oder ob es eine Möglichkeit gibt, auf die Funktion funktion(point) zu verzichten.

    1. Hallo und Danke

      Erstmal Tschuldige fürs unleserliche Einfügen des Codes!

      Nun zum Inhalt:
      Ich kapier das ja selber nicht so ganz... habs solange hin und her kopiert bis es ging. Okay ich erkläre es mal:

      Diese Codeauszug ist aus der Function load der, soweit ich das verstanden habe, beim laden der Seite aufgerufen wird.

      Das x in der function nicht existiert wusste ich nicht, klingt aber einleuchtend. Mein Problem ist: ich verstehe selber nicht so genau was die function(point) macht. Ich weiss nur das nachher in der Variable [oder function??] point nachher Koordinaten drin stehen. Spich: getLatLng übergebe ich eine Adresse, und diese Function errechnet mit die GPS-Koordinaten, die nachher in Point stehen. Ich habe es leider nicht geschafft diese Koordinaten nach der Funktion noch irgendwo greifbar zu machen.

      Deshalb habe ich das setzen des Pnktes (map.addOverlay(createMarker(point, x, adresse,imageURL));) innerhalb diese Function gemacht.

      DU sagst x existiert nicht... aber wieso nimmt er dann von imageURL,adresse und x immer den höchsten wert, als sei die Schleife fertig duchlaufen??

      Das auskommentierte hat funktioniert ja. Aber bei diesem muss ich die fertige koordinaten übergeben, an die ich ja, wie ich oben versucht habe zu beschreiben, nachher nicht mehr dran komme.

      LG
      Michael

      Hier nochmal das GANZE Script incl. HTML. Ich hab versucht es möglichst leserlich zu formatieren...

      [CODE]
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
          <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
          <title>Google Maps JavaScript API Example</title>
          <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAA605BgTil4DmxL2u_1r98LBRmjsAhTEwM-0DrLbvZ_nDfDNWL6RQwmPVSpD6U3cUNJqUxN4HTyfWiSQ"
            type="text/javascript"></script>
          <script type="text/javascript">

      function load() {
            if (GBrowserIsCompatible()) {
          var map = new GMap2(document.getElementById("map"));
          var geocoder = new GClientGeocoder();

      var baseIcon = new GIcon();
              baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
              baseIcon.iconSize = new GSize(6, 7);
              baseIcon.shadowSize = new GSize(6, 7);
              baseIcon.iconAnchor = new GPoint(9, 34);
              baseIcon.infoWindowAnchor = new GPoint(9, 2);
              baseIcon.infoShadowAnchor = new GPoint(18, 25);

      function createMarker(point, index,TTtext,iconURL) {
                // Create a lettered icon for this point using our icon class
                var letter = String.fromCharCode("A".charCodeAt(0) + index);
                var letteredIcon = new GIcon(baseIcon);
                letteredIcon.image = iconURL;

      // Set up our GMarkerOptions object
                markerOptions = { icon:letteredIcon };
                var marker = new GMarker(point, markerOptions);

      GEvent.addListener(marker, "click", function() {
                  marker.openInfoWindowHtml(TTtext);
                });
                return marker;
              }

      map.setCenter(new GLatLng(37.4419, -122.1419), 8);
                   map.addControl(new GLargeMapControl());
                                   map.addControl(new GMapTypeControl());

      GDownloadUrl("datax.xml", function(data) {
                var xml = GXml.parse(data);
                var markers = xml.documentElement.getElementsByTagName("marker");
                for (var x = 0; x < markers.length; x++) {
                  var latlng = new GLatLng(parseFloat(markers[x].getAttribute("lat")), parseFloat(markers[x].getAttribute("lng")));
            var tooltext = markers[x].getAttribute("tooltext");
            var imageURL =markers[x].getAttribute("image");
            var adresse =markers[x].getAttribute("adresse");

      geocoder.getLatLng(adresse,
               function(point) {
                 if (!point) {
                   alert(address + " not found");
                 } else {
                   map.setCenter(point, 7);
               map.addOverlay(createMarker(point, x, adresse,imageURL));
              }
              });

      }
              });

      }}

      //]]>
          </script>
        </head>
        <body onload="load()" onunload="GUnload()">
          <div id="map" style="width: 1200px; height: 500px"></div>
        </body>
      </html>
      [/CODE]

      1. Yerf!

        DU sagst x existiert nicht... aber wieso nimmt er dann von imageURL,adresse und x immer den höchsten wert, als sei die Schleife fertig duchlaufen??

        Durch die anonyme Funktion die x (welches Außerhalb deklariert ist) referenziert entsteht ein Closure, dadurch kann weiterhin auf x zugegriffen werden, auch wenn die Schleife schon fertig durchgelaufen ist.

        Allerdings arbeitet eine for-Schleife iterativ und nicht rekursiv: es entsteht nur ein Gültigkeitsbereich für Variablen und damit nur ein Closure für alle Funktionen. Damit referenzieren alle Funktionen das selbe x, weches nach dem Schleifendurchlauf eben auf dem Endwert steht.

        Wie man disen Knoten am besten löst kann ich dir aber im Moment auch nicht sagen...

        Gruß,

        Harlequin

        --
        <!--[if IE]>This page is best viewed with a webbrowser. Get one today!<![endif]-->
  2. Was übersehe ich oder verstehe ich falsch?

    Die Erklärung hast du ja bereits. Es gibt mehrere Wege dieses Problem zu lösen. Die einfachste ist es dem entsprechendem Objekt die Zählvariabel als Attribut anzuhängen, ist in deinem Fall aber nicht ratsam, da es nicht deine eigenen Objekte sind.

    Also muss du eine Funktion erzeugen,

     var erzeugeFunktion = function(c) {  
      return function(point) {  
       if (!point) {  
        alert(address + " not found");  
       } else {  
       map.setCenter(point, 13);  
       map.addOverlay(createMarker(point, c, adresse,imageURL));  
       }  
      }  
     };  
      
     geocoder.getLatLng(adresse, erzeugeFunktion(x));  
    
    

    Struppi.

    1. Was übersehe ich oder verstehe ich falsch?

      Die Erklärung hast du ja bereits. Es gibt mehrere Wege dieses Problem zu lösen. Die einfachste ist es dem entsprechendem Objekt die Zählvariabel als Attribut anzuhängen, ist in deinem Fall aber nicht ratsam, da es nicht deine eigenen Objekte sind.

      Danke vielmals! Ich habe den Code ein wenig ändern müssen aber das war nur weil ich noch einen kleinen Fehler hatte!

      Ich komme aus der VB-Welt und die ist doch anders als JS oder C :)

      ALso nochmal danke an alle

      LG
      MIchael