Du befindest Dich im Archiv vom ABAKUS Online Marketing Forum. Hier kannst Du Dich für das Forum mit den aktuellen Beiträgen registrieren.

JS/Ajax Reihenfolge Funktionen

Ajax, Hijax, Microformats, RDF, Markup, HTML, PHP, CSS, MySQL, htaccess, robots.txt, CGI, Java, Javascript usw.
Neues Thema Antworten
Synonym
PostRank 10
PostRank 10
Beiträge: 3708
Registriert: 09.08.2008, 02:55

Beitrag von Synonym » 14.02.2010, 14:42

Hallo zusammen,

also ich habe mal eine Frage, da ich nun schon 3 Tage mit zwei winzigen Funktionen rummache und keine Lösung finde. Bin für JS wohl wirklich zu doof.

Ich habe eine kleine Funktion

Code: Alles auswählen

function setMyCenter()
{
	debug('setMyCenter');
	// Wenn centerBounds nicht vorhanden, 
	// dann centerBounds aus Datenbank laden und generieren
	if(!centerBounds)
	{
		debug('centerBounds not set');
		loadMyCenter();
	}
	
	debug('centerBounds3 '+centerBounds);
}
Wie man sieht, soll wenn centerBounds nicht vorhanden ist eine zweite Funktion aufgerufen werden, die dann den Wert ermittelt. Auch dies derzeit sehr einfach gehalten.

Code: Alles auswählen

function loadMyCenter()
{
	debug('loadMyCenter from Database');
	centerBounds = 'test';
	debug('centerBounds2 '+centerBounds);
}

So eigentlich sollte dabei etwas rauskommen wie:
setMyCenter
centerBounds not set
loadMyCenter from Database
centerBounds2 test
centerBounds3 test

Allerdings scheint da wohl die Reihenfolge nicht zu passen, nur warum, das ist mein Problem...
setMyCenter
centerBounds not set
loadMyCenter from Database
centerBounds3 false
centerBounds2 test

Weiß einer wie ich das lösen kann - irgendwie muss es ja gehen.

Anzeige von ABAKUS

von Anzeige von ABAKUS »

Content Erstellung von ABAKUS Internet Marketing
Ihre Vorteile:
  • einzigartige Texte
  • suchmaschinenoptimierte Inhalte
  • eine sinnvolle Content-Strategie
  • Beratung und Umsetzung
Jetzt anfragen: 0511 / 300325-0

Mork vom Ork
PostRank 9
PostRank 9
Beiträge: 2557
Registriert: 08.07.2008, 11:07
Wohnort: Aufm Friedhof.

Beitrag von Mork vom Ork » 14.02.2010, 17:34

Poste mal den ganzen Code, der Ausschnitt da oben funktioniert wie erwartet (siehe unten).

Im Moment lässt sich dazu nur allgemein sagen, dass das erste A in Ajax für asynchron steht. Falls du also irgendwo außerhalb des zitierten Ausschnittes tatsächlich Ajax einsetzt, wäre die Abfolge möglicherweise erklärbar. Mit den bis jetzt vorliegenden Informationen ist sie es leider nicht, dies …

Code: Alles auswählen

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http&#58;//www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title></title>

<script type="text/javascript">

var debug = console.debug;
var centerBounds;

function setMyCenter&#40;&#41; 
&#123; 
   debug&#40;'setMyCenter'&#41;; 
   // Wenn centerBounds nicht vorhanden, 
   // dann centerBounds aus Datenbank laden und generieren 
   if&#40;!centerBounds&#41; 
   &#123; 
      debug&#40;'centerBounds not set'&#41;; 
      loadMyCenter&#40;&#41;; 
   &#125; 
    
   debug&#40;'centerBounds3 '+centerBounds&#41;; 
&#125;

function loadMyCenter&#40;&#41; 
&#123; 
   debug&#40;'loadMyCenter from Database'&#41;; 
   centerBounds = 'test'; 
   debug&#40;'centerBounds2 '+centerBounds&#41;; 
&#125;

</script>

</head>

<body onLoad="setMyCenter&#40;&#41;">

</body>

</html>
&#8230; ergibt das &#8230;

Code: Alles auswählen

setMyCenter z.html &#40;Zeile 14&#41;
centerBounds not set z.html &#40;Zeile 19&#41;
loadMyCenter from Database z.html &#40;Zeile 28&#41;
centerBounds2 test z.html &#40;Zeile 30&#41;
centerBounds3 test z.html &#40;Zeile 23&#41;

Synonym
PostRank 10
PostRank 10
Beiträge: 3708
Registriert: 09.08.2008, 02:55

Beitrag von Synonym » 14.02.2010, 18:03

Ah ok, dann liegt es wohl wirklich daran. Ein kleiner Teil fehlt, den hatte ich extra weg gelassen, damit es nicht zu unübersichtlich wird.

An sich passt das da oben schon so, nur in der zeiten Funktion steht anstelle von "centerBounds = 'test';" das hier:

Code: Alles auswählen

var urlstr = "region-center.php";
var request = google.maps.XmlHttp.create&#40;&#41;;

request.open&#40;"GET", urlstr, true&#41;;
request.onreadystatechange = function&#40;&#41;
&#123;
	if &#40;request.readyState == 4&#41;
	&#123;
		var xmlCenterDoc = request.responseXML;
		var locations = xmlCenterDoc.documentElement.getElementsByTagName&#40;"location"&#41;;
		centerBounds = map.getBounds&#40;&#41;;
		
		if &#40;locations.length&#41;
		&#123;
		     centerBounds = new google.maps.LatLngBounds&#40;&#41;;
		     for &#40;var i = 0; i < locations.length; i++&#41;
			&#123;
				var point = new google.maps.LatLng&#40;locations&#91;i&#93;.getAttribute&#40;"lat"&#41;, locations&#91;i&#93;.getAttribute&#40;"lng"&#41;&#41;;
				centerBounds.extend&#40;point&#41;;
			&#125;
		&#125;
	&#125;
&#125;
request.send&#40;null&#41;;
Und ja, liegt wohl daran, dass es asynchron ist, zumindest geben das viele andere Quellen her, auch wenn immer ohne Lösung. Die einzige die es bisher gab war eine mit "anonyme Funktionen", aber da kam ich dann auch nicht weiter.

Edit:
Ganz darüber gibt es noch die Funktion zur Initaliesierung

Code: Alles auswählen

var centerBounds = false;

google.load&#40;"maps", "2.x",&#123;"other_params"&#58;"sensor=true","locale"&#58;"de_DE"&#125;&#41;;

google.setOnLoadCallback&#40;initialize&#41;;

function initialize&#40;&#41;
&#123;
	debug&#40;'initialize'&#41;;
	if&#40;google.maps.BrowserIsCompatible&#40;&#41;&#41;
	&#123;
		map = new google.maps.Map2&#40;document.getElementById&#40;'mapdiv'&#41;&#41;;
		//map.addControl&#40;new google.maps.MapTypeControl&#40;&#41;&#41;;
		map.disableScrollWheelZoom&#40;&#41;;
		
		setMyCenter&#40;&#41;;
		
		myLargeMapControl = new google.maps.LargeMapControl&#40;&#41;;
		myOverviewMapControl = new google.maps.OverviewMapControl&#40;&#41;;
		myMapTypeControl = new google.maps.MapTypeControl&#40;&#41;;
		
		map.disableDragging&#40;&#41;;
	&#125;
&#125;
Die region-center.php liefert

Code: Alles auswählen

<locations>
<location lat="52.383858" lng="13.150482" />
<location lat="52.634499" lng="13.722090" />
</locations>
Ich habe derzeit schon eine Lösung gefunden, aber gefallen tut die mir nicht wirklich. In der zweiten Funktion prüfe ich nun einfach nochmals, ob "centerBounds" vorhanden ist. Wenn ja, dann wird setMyCenter() nochmals aufgerufen. Wenn nicht, dann wird ein standard-Wert gesetzt.

Die "Reihenfolge" wäre da zwar immer noch falsch, aber es funktioniert soweit. Nur ich finde das irgendwie extrem umständlich und kann mir nicht vorstellen, dass das so normal ist.

Anzeige von ABAKUS

von Anzeige von ABAKUS »

SEO Consulting bei ABAKUS Internet Marketing
Erfahrung seit 2002
  • persönliche Betreuung
  • individuelle Beratung
  • kompetente Umsetzung

Jetzt anfragen: 0511 / 300325-0.


Mork vom Ork
PostRank 9
PostRank 9
Beiträge: 2557
Registriert: 08.07.2008, 11:07
Wohnort: Aufm Friedhof.

Beitrag von Mork vom Ork » 14.02.2010, 21:18

Rufe einfach in der onreadystatechange-Funktion, d.h. dann, wenn centerBounds gefüllt wurde, setMyCenter() nochmals auf. Dazu machst du Folgendes:

setMyCenter() muss lediglich dahingehend geändert werden, dass es, falls centerBounds nicht existiert, außer dem Anstoßen des Nachladens gar nichts macht:

Code: Alles auswählen

function setMyCenter&#40;&#41; 
&#123; 
    if &#40;!centerBounds&#41; // kein centerBounds
    &#123; 
        loadMyCenter&#40;setMyCenter&#41;; // centerBounds nachladen und setMyCenter erneut ausführen
    &#125;
    else // centerBounds existiert
    &#123; 
        irgendwas_mit _centerBounds_anstellen;
    &#125;
    // Beide centerBounds-Fälle abgearbeitet, hier nüscht mehr!
&#125;
loadMyCenter wird dahingehend geändert, dass es eine beliebige Funktion als Argument akzeptiert, die ausgeführt wird, sobald centerBounds geladen wurde. Auch Funktionen sind in Javascript Objekte, man kann mit ihnen so umgehen wie mit dem Inhalt jeder anderen Variable, einschließlich der Übergabe als Argument.

Code: Alles auswählen

function loadMyCenter&#40;aktion&#41; 
&#123; 
    var urlstr = "region-center.php";
    var request = google.maps.XmlHttp.create&#40;&#41;;

    request.open&#40;"GET", urlstr, true&#41;;
    request.onreadystatechange = function&#40;&#41;
    &#123;
        if &#40;request.readyState == 4&#41;
        &#123;
            var xmlCenterDoc = request.responseXML;
            var locations = xmlCenterDoc.documentElement.getElementsByTagName&#40;"location"&#41;;
            centerBounds = map.getBounds&#40;&#41;;
            if &#40;locations.length&#41;
            &#123;
                centerBounds = new google.maps.LatLngBounds&#40;&#41;;
                for &#40;var i = 0; i < locations.length; i++&#41;
                &#123;
                    var point = new google.maps.LatLng&#40;locations&#91;i&#93;.getAttribute&#40;"lat"&#41;, locations&#91;i&#93;.getAttribute&#40;"lng"&#41;&#41;;
                    centerBounds.extend&#40;point&#41;;
                &#125;
                if &#40;aktion&#41; // wir sollen eine Funktion ausführen, sobald centerBounds startklar ist&#58;
                &#123;
                    aktion&#40;&#41;; // aktion ist eine Variable, die eine Funktion enthält!
                &#125;
            &#125;
        &#125;
    &#125;
    request.send&#40;null&#41;;
&#125;
Der direkte Aufruf von setMyCenter() wäre auch möglich gewesen, aber mit der Übergabe als Argument bist du flexibler. Ich weiß nicht, ob du loadMyCenter() noch von anderen Stellen aus aufrufst und an diesen anderen Stellen möchtest du setMyCenter() eventuell ja nicht ausgeführt haben &#8211; daher die Übergabe als Argument.

Synonym
PostRank 10
PostRank 10
Beiträge: 3708
Registriert: 09.08.2008, 02:55

Beitrag von Synonym » 15.02.2010, 09:43

Hi Mork vom Ork,
danke Dir für Deine Antwort, auch wenn ich mir den Teil insbesondere mit "aktion" nochmal genau überdenken muss. Ist jetzt nicht gerade Bahnhof, aber eine Bushaltestelle schon :-)

Ansonsten hört sich das was Du sagt so an wie das, was ich in meinem beiden letzten Absätzen geschrieben hatte, nur dass meine Umsetzung etwas anders aussieht. Dachte eigentlich das wäre komplett falsch :)

Code: Alles auswählen

function setMyCenter&#40;&#41;
&#123;
	if&#40;!centerBounds&#41;
	&#123;
		loadMyCenter&#40;&#41;;
	&#125;
	else
	&#123;
		map.setCenter&#40;centerBounds.getCenter&#40;&#41;&#41;;
		map.setZoom&#40;map.getBoundsZoomLevel&#40;centerBounds&#41;&#41;;
	&#125;
&#125;

function loadMyCenter&#40;&#41;
&#123;
	var urlstr = "region-center.php";
	var request = google.maps.XmlHttp.create&#40;&#41;;
	
	request.open&#40;"GET", urlstr, true&#41;;
	request.onreadystatechange = function&#40;&#41;
	&#123;
		if &#40;request.readyState == 4&#41;
		&#123;
			var xmlCenterDoc = request.responseXML;
			
			var locations = xmlCenterDoc.documentElement.getElementsByTagName&#40;"location"&#41;;
			centerBounds = map.getBounds&#40;&#41;;
			
			if &#40;locations.length&#41;
			&#123;
     			centerBounds = new google.maps.LatLngBounds&#40;&#41;;
     			for &#40;var i = 0; i < locations.length; i++&#41;
				&#123;
					var point = new google.maps.LatLng&#40;locations&#91;i&#93;.getAttribute&#40;"lat"&#41;, locations&#91;i&#93;.getAttribute&#40;"lng"&#41;&#41;;
					centerBounds.extend&#40;point&#41;;
				&#125;
			&#125;
			if&#40;centerBounds&#41; setMyCenter&#40;&#41;;
			else map.setCenter&#40;&#41;; // default
		&#125;
	&#125;
	request.send&#40;null&#41;;
&#125;
Die "loadMyCenter" wird eigentlich nur einmal ausgeführt, bzw. sollte sie. (Kann aber sein, dass das noch anders wird). Die "setMyCenter" wird öfters benutzt und einigen anderen Funktionen. Daher auch die Teilung, denn ein stetiger neuer Abruf aus der DB ist da ja nicht nötig. Randpunkte bleiben gleich, nur Zoomstufen und Kartengrößen ändern sich.

Werde das mit dem Aktion nun aber auch mal antesten. Mal sehen was sich da tut :)

Danke und Gruß

Nachtrag:
Ok, das mit dem "aktion" habe ich nun verstanden. Hatte da echte Probleme mit, wenn Variablen (Objekte) und Funktionen genauso heißen. Funktioniert so aber genauso wie mit meiner Umsetzung.

Aber eine Frage noch:
aber mit der Übergabe als Argument bist du flexibler
In Bezug auf was? Was wäre da denn genau der Unterschied dazu? Ich könnte ein anderes Argument übergeben, ok, das ist klar, aber das gibt es nie. Hat es noch andere Unterschiede?

Mork vom Ork
PostRank 9
PostRank 9
Beiträge: 2557
Registriert: 08.07.2008, 11:07
Wohnort: Aufm Friedhof.

Beitrag von Mork vom Ork » 15.02.2010, 12:58

Synonym hat geschrieben:Ansonsten hört sich das was Du sagt so an wie das, was ich in meinem beiden letzten Absätzen geschrieben hatte, nur dass meine Umsetzung etwas anders aussieht. Dachte eigentlich das wäre komplett falsch :)
Du hattest damit schon den vollkommen richtigen Ansatzpunkt gefunden, für die Umsetzung gibt's allerdings einen Abzug in der B-Note :) Dies ist dein Code:

Code: Alles auswählen

if &#40;locations.length&#41;
&#123;
    centerBounds = new google.maps.LatLngBounds&#40;&#41;;
    for &#40;var i = 0; i < locations.length; i++&#41;
    &#123;
        var point = new google.maps.LatLng&#40;locations&#91;i&#93;.getAttribute&#40;"lat"&#41;, locations&#91;i&#93;.getAttribute&#40;"lng"&#41;&#41;;
        centerBounds.extend&#40;point&#41;;
    &#125;
&#125;
if&#40;centerBounds&#41; setMyCenter&#40;&#41;;
else map.setCenter&#40;&#41;; // default
Du hast direkt über deiner if(centerBound)-Bedingung einen weiteren if-Block (prüft locations.length). In diesem Block wird centerBounds erzeugt, so dass du auf deine eigene if-Bedinung verzichten könntest, wenn du den setMyCenter()-Aufruf einfach eine Zeile höher in diesen Block verschiebst:

Code: Alles auswählen

if &#40;locations.length&#41;
&#123;
    centerBounds = new google.maps.LatLngBounds&#40;&#41;;
    for &#40;var i = 0; i < locations.length; i++&#41;
    &#123;
        var point = new google.maps.LatLng&#40;locations&#91;i&#93;.getAttribute&#40;"lat"&#41;, locations&#91;i&#93;.getAttribute&#40;"lng"&#41;&#41;;
        centerBounds.extend&#40;point&#41;;
    &#125;
    setMyCenter&#40;&#41;;
&#125;
else // locations.length == 0
&#123;
    map.setCenter&#40;&#41;; // default
&#125;
Schaust du nach dieser kleinen Änderung nochmal in meinen Ansatz mit aktion() weiter oben, wirst du feststellen, dass er in der Tat nahezu identisch mit deinem ist. Oder kurz: Eigentlich konntest du dir sehr gut selbst helfen :)
das mit dem "aktion" habe ich nun verstanden. Hatte da echte Probleme mit, wenn Variablen (Objekte) und Funktionen genauso heißen.
Wie gesagt, in Javascript ist alles ein Objekt, auch eine Funktion. Deshalb stecken Funktionen eigentlich ebenfalls in Variablen, eine Funktionsdefinition, wie du sie als function bla() {&#8230; kennst, erzeugt eigentlich eine Variable bla vom Typ function, ist also identisch mit var bla = function () {&#8230; Probier's aus:

Code: Alles auswählen

function a&#40;&#41; &#123;
    alert&#40;"Funktion A"&#41;;
&#125;

function b&#40;&#41; &#123;
    alert&#40;"Funktion B"&#41;;
&#125;

var funktion = function &#40;&#41; &#123;
    alert&#40;"Ursprüngliche Funktion"&#41;;
&#125;

// funktion&#40;&#41; mit ursprünglichem Inhalt aufrufen.
funktion&#40;&#41;;

// funktion durch den Code von Funktion a ersetzen&#58;
funktion = a;
funktion&#40;&#41;;

// funktion durch den Code von Funktion b ersetzen&#58;
funktion = b;
funktion&#40;&#41;;
Dementsprechend lassen sich Funktionen auch ganz normal als Argument übergeben.
aber mit der Übergabe als Argument bist du flexibler
In Bezug auf was? Was wäre da denn genau der Unterschied dazu? Ich könnte ein anderes Argument übergeben, ok, das ist klar, aber das gibt es nie.
Ich wusste nicht, wo du überall centerBounds benötigst und von wo aus du dementsprechend loadMyCenter() aufrufen müsstest. Gibt es neben setMyCenter() noch eine Funktion, die centerBounds verwendet, zB andererCenter() wäre es unklug, in loadMyCenter() fix setMyCenter() aufzurufen &#8211; dann rufst du andererCenter() auf, andererCenter() ruft loadMyCenter() auf und dieses dann setMyCenter(), obwohl du eigentlich andererCenter() haben wolltest.

Mit dem Funktions-Argument bei loadMyCenter() hast du mehr Kontrolle:

Code: Alles auswählen

function setMyCenter&#40;&#41; 
&#123; 
   if&#40;!centerBounds&#41; // centerBounds existiert noch nicht, laden
   &#123; 
      loadMyCenter&#40;setMyCenter&#41;; 
   &#125; 
   else 
   &#123; 
      map.setCenter&#40;centerBounds.getCenter&#40;&#41;&#41;; 
      map.setZoom&#40;map.getBoundsZoomLevel&#40;centerBounds&#41;&#41;; 
   &#125; 
&#125;
function andererCenter&#40;&#41; 
&#123; 
   if&#40;!centerBounds&#41;  // centerBounds existiert noch nicht, laden
   &#123; 
      loadMyCenter&#40;andererCenter&#41;; 
   &#125; 
   else 
   &#123; 
        centerBounds.irgendwas_anderes&#40;&#41;;
   &#125; 
&#125;
Ist hingegen sichergestellt, dass loadMyCenter() immer nur von setMyCenter() aufgerufen wird, brauchst du das nicht. Allerdings wäre dann die Frage, warum du loadMyCenter() überhaupt in eine separate Funktion ausgelagert hast &#8211; sowas macht man ja nur, wenn man den Inhalt von verschiedenen Stellen aus aufruft.

Synonym
PostRank 10
PostRank 10
Beiträge: 3708
Registriert: 09.08.2008, 02:55

Beitrag von Synonym » 15.02.2010, 13:15

Hi

Also das mit dem unnötigen "if" beim centerBounds kann ich gut verstehen. Wird noch geändert. Bin eh gerade dabei das Teil zu optimieren.

Code: Alles auswählen

var bla = function &#40;&#41; &#123;
Ha! und genau das function bla() {} war für mich gedanklich immer was anderes als var bla = function() {} Das sind so Dinge wo ich beim JS wirklich verzweifle oder besser gesagt, nicht verstanden hatte. Also gut zu wissen :-)

Auch Dein anderer Ansatz passt.
Neben setMyCenter() verwendet keine anderer Funktion die centerBounds. Getrennt waren die ja wie gesagt nur deswegen, dass ich wenn das Script geladen ist, direkt auf "setMyCenter" zugreifen kann, ohne die Daten neu aus der Datenbank laden zu müssen.

Aber die Frage nach dem "warum getrennt" habe ich mir zwischenzeitlich auch schon gestellt. Theoretisch könnte das alles in eine Funktion. Wenn centerBounds nicht vorhanden, dann laden, ansonsten eben nicht.

Aber das gehört bei mir nun in den Bereich "optimieren", den ich oben erwähnt hatte. Habe da so einige kleine Funktionen die eigentlich alle kombiniert werden können, da sie immer aufeinander beruhen.

Danke Dir!

Gruß

Antworten
  • Vergleichbare Themen
    Antworten
    Zugriffe
    Letzter Beitrag