AJAX modyfikuje zawartość tylko ostatniego div-a

0

Chodzi o to, że gdy chcę zmienić zawartość kilku div-ów to wszystkie zostają bez zmian poza ostatnim który wyświetla prawidłowe dane.

kod JS

var XMLHttpRequestObject = false;

if(window.XMLHttpRequest){
	XMLHttpRequestObject = new XMLHttpRequest();
} else if(window.ActiveXObject){
	XMLHttpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");
}

function dane_get(dest, src) {
	if(XMLHttpRequestObject) {
		var div = document.getElementById(dest);
		XMLHttpRequestObject.open("GET", src);

		XMLHttpRequestObject.onreadystatechange = function() {
			if(XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200) {
				div.innerHTML = XMLHttpRequestObject.responseText;
			}
		}

		XMLHttpRequestObject.send(null);
	}
}

html

  <div id="div1">d1</div>
  <div id="div2">d2</div>
  <div id="div3">d3</div>

i teraz po wywołaniu tego w taki sposób:

<input type="button" value="Kliknij tu" onclick="dane_get('div1', 'dane.php'); dane_get('div2', 'dane.php'); dane_get('div3', 'dane.php');" />

div-y 1 oraz 2 pozostają nie ruszone tylko trzeci przyjmuje wartość dane bo tylko to wyświetla plik dane.php

przy użyciu zwykłej funkcji

function dane_tekst(dest, dane) {
	var div = document.getElementById(dest);
	div.innerHTML = dane;
}

problem ten nie występuje

1

Bo masz jeden obiekt XMLHttpRequestObject, wspólny dla wszystkich żądań. Przy każdym wywołaniu dane_get() nadpisujesz funkcjęonreadystatechange.

Utwórz nowy obiekt XMLHttpRequestObject na początku wywołania dane_get(). Obiekt ten zapisz do zmiennej lokalnej. Czyli: przenieść pierwsze 7 linijek skryptu na początek treści funkcji dane_get(). (Tak naprawdę to powinieneś wydzielić osobną funkcję tworzącą obiekt XmlHttpRequest)

0

Dzięki bardzo bswierczynski. Działa jak trzeba w takim razie w jakim celu powinienem wydzielić osobną funkcję do tego? Sorry, że tak się dopytuję o szczegóły które są pewnie banalne ale dopiero raczkuję z ajaxem

0

Nie chodzi o Ajax, tylko o inżynierię oprogramowania. Jakość kodu.

To taki zbiór uniwersalnych zasad, które można stosować w zasadzie niezależnie od języka programowania.

Jedna z nich mówi: "funkcja powinna wykonywać jedną, dobrze określoną czynność". Inne zasady mówią o tworzeniu reużywalnego kodu. Jeszcze inne o poziomach abstrakcji. Szczególnie Wujek Bob (Robert C. Martin) promuje zasadę, wg której w ciele funkcji powinny się znajdować instrukcje o jeden poziom abstrakcji niżej w porównaniu do poziomu abstrakcji funkcji jako całości.

W Twojej nowej wersji funkcji górne kilka linijek będzie stanowiło oddzielną, niezależną, dobrze zdefiniowaną czynność. Tworzenie obiektu XMLHttpRequest (w skrócie XHR). To czynność bardzo szczegołowa, zależna od implementacji (środowiska przeglądarki). Jest bardziej techniczna niż cała reszta funkcji.

Programista-student, który stara się być dobrym programistą, może poprzedziłby tę sekcję komentarzem // tworzenie obiektu XHR.

No i jeśli ukryjemy tę czynność wewnątrz funkcji dane_get(), to nie będziemy mogli użyć jej ponownie w innym miejscu aplikacji.

Wszystkie te problemy rozwiązuje wydzielenie funkcji. Komentarz jest gorszy niż funckja o odpowiedniej nazwie. Wydzielasz te parę linijek do osobnej funkcji, nazywasz ją utwórzXHR() i masz funkcję, która ma jedno, dobrze zdefiniowane zadanie, a w swoim wnętrzu schodzi tylko o jeden poziom abstrakcji (poziom szczegółów) głębiej.

Zauważ, że "wysłanie żądania" to też jedno zadanie, na które składa się utworzenie obiektu XHR. Więc funckja dane_get niby mogłaby właśnie je realizować, ale gdybyś napisał w kilku punktach sposób działania tej funkcji, to pierwszym punktem byłoby "utwórz obiekt XHR" i dopiero w tym punkcie byłyby podpunkty "jeśli konstruktor window.XHR istnieje, to go użyj; w przeciwnym wypadku użyj ActiveX-a / jeszcze czegoś innego". Istnienie takich podpunktów świadczy o tym, że mamy za dużo poziomów abstrakcji. Powinniśmy zostawić tylko punktu nadrzędne, a szczegóły ukryte w podpunktach przenieść do osobnych funkcji.

Czasem to jest trochę płynne i dyskusyjne, ale w tym wypadku akurat dyskusji nie ma. Tworzenie obiektu XHR to czynność tak oddzielna, dobrze zdefiniowana i przydatna, że bardzo opłaca się ją mieć w osobnej funkcji.

Kod, który wkleiłeś, ma jeszcze inne problemy od strony inżynierii oprogramowania. Tj. czytelności, zrozumiałości kodu, a także jego podatności na modyfikację i reużycie.

Np. nazwy parametrów src i dest wydają się na początku logiczne, bo np. w C tradycyjnie tak się nazywało podobne parametry w funkcjach typu strcpy. Ale tutaj... te nazwy sugerują podobieństwo, a w rzeczywistości src i dest to zupełnie różne rzeczy! Różne pod względem typu i koncepcji.

src to tak naprawdę adres, pod który ślemy zapytanie. Pewnie parametr powinien nazywać się url. Z kolei dest to... ID elementu, do którego wstawiamy wynik zwrócony przez serwer, co bardziej opisałaby nazwa outputElementId.

Te problemy nie dają się we znaki przy tak małym i prostym kodzie, ale przy większych aplikacjach -- i owszem. Ja np. pracuję przy aplikacjach, gdzie bazowe frameworki mają dziesiątki/setki tysięcy linii kodu w JavaScripcie, a każda nowa aplikacja dorzuca parę ładnych tysięcy od siebie. Projekty nie są na ogół jednoosobowe, a z bazy kodu korzysta tak naprawdę z tuzin osób.

Nawet małe projekty cierpią, gdy "już są prawie skończone". Jakoś tak dodawanie każdej pierdoły jest dużo trudniejsze niż na początku i w kodzie ciężko się połapać. Właśnie m.in. ze względu na słabą jakość kodu.

Pomyśl co by się dzieje w projektach, które mają te tysiące czy setki tysięci linii i w których nikt nie dba o jakość... Dlatego my dbamy :).

1 użytkowników online, w tym zalogowanych: 0, gości: 1