[AJAX] Odbiór danych

0
function handle_check3()
{
        if((ajax.readyState==4)&&(ajax.status==200))
        {
                rezult = ajax.responseText;
                alert('Rezultat w handlecheck' + rezult);
        }
}

//--------------------------

function katal_add(vkatalog)
{
        if(ajax)
        {
               ajax.open('post', 'ajax.php?s=katal_add');
                ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
               ajax.send("nazwa=" + encodeURIComponent(vkatalog) + "&priv=1&haslo=");
               ajax.onreadystatechange = handle_check3;

                alert('Rezultat: '+rezult);
                if((rezult != 0) || (rezult != NULL)){
                        document.nowy_kod_frm.katalog.options[document.nowy_kod_frm.katalog.options.length] = new Option(vkatalog, rezult, false, true);
                        alert('nowa pozycja aaaaaaaaaaaaaaaaaaaaaaa');
                } else {
                        alert('nim0');
                }
        }
}

Mam sobie taki o to JS. Działa to tak.
User wchodzi na stronę, ma listę wyboru. Obok przycisk dodaj, który wywołuje funkcję katal_add
Następnie przesyłane postem zmienne do pliku ajax.php tworzą nową pozycję w bazie danych. Dalej zaczynają się schody.
Chciałbym by pole wyboru po dodaniu wartości do bazy przytyło również o nowy rekord.

Plik ajax.php zwraca 0 dla niepowodzenia lub ID nowego rekordu i funkcja handle_check3 powinna ją przypisać do zmienne rezult, która następnie zostaje przetworzona w warunku w katal_add, tak niestety się nie dzieje.

Teraz tak:
rezultat w funkcji handle_check3 jest poprawny(wyświetla ID katalogu), ale już alert w funkcji katal_add() wyświetla undefined. No i po dodaniu do bazy danych ID jest 0.

Teraz wiem, że funkcja onreadystatechange wykona się dopiero po zmianie statusu żądania, więc nie będzie "czekać" na przypisanie wartości do zmiennej, tylko "pójdzie" dalej.
Próbowałem jakoś uruchomić synchronicznie:

ajax.open('post', 'ajax.php?s=katal_add', false);

Ale też nic nie daje. W jaki sposób mogę sprawić, żeby dopiero po przypisaniu zmiennej wykonała się dalsza część skryptu.

Pzdr

0

A nie moglbyś tej listy rozwijanej umiescic w jakims divie w php zrobic selekta wszystkich opcji wpisac je do jednej zmiennej z tagami listy rozwijanej i po prostu podmienic kod w divie?

0

Nie moge

0

Po pierwsze to praktycznie nigdy nie powinieneś wykonywać żądań Ajaxa synchronicznie. W takim wypadku na ogół lepiej w ogóle zrezygnować z Ajaxa. Użycie trybu synchronicznego powoduje, że cały interfejs użytkownika jest zamrożony do chwili nadejścia odpowiedzi -- użytkownik nie może nic zrobić; przeglądarka może nawet wyświetlić kursor z klepsydrą i dosłownie zamrozić całą stronę.

Musisz to zakodować asynchronicznie.

Chyba po prostu jeszcze nie bardzo Ci wychodzi asynchroniczne myślenie ;-). Nie mam pewności, czy zrozumiałem co chcesz osiągnąć, ale wydaje mi się, że można to zrobić łatwo. Chcesz, by instrukcje z funkcji katalog_add od pierwszego alerta (włącznie) do końca funkcji wykonały się dopiero po przyjściu odpowiedzi z serwera? Nie ma problemu! Przenieś te instrukcje do handle_check, zaraz za rezult=ajax.responseText. Zauważ proszę, że wtedy ze zmiennej rezult możesz zrobić zmienną lokalną, a nie globalną. Cała reakcja na odpowiedź będzie się bowiem odbywała lokalnie, w funkcji handle_check3. Nastawienie na zmienne globalne to bardzo zła praktyka programistyczna, a promowanie jej to jeden z największych błędów języka JavaScript.

0

Nie da się ukryć, że AJAX nie jest moją mocną stroną jak na razie :)
W każdym razie uczyniłem tak jak powiedziałeś i tak:

function handle_check3()
{
	var rezult;
	if((ajax.readyState==4)&&(ajax.status==200))
	{
		rezult = ajax.responseText;
		alert('Rezultat: '+rezult); //1
		if((rezult != 0) || (rezult != NULL)){
			document.nowy_kod_frm.katalog.options[document.nowy_kod_frm.katalog.options.length] = new Option(vkatalog, rezult, false, true);
			alert('nowa pozycja aaaaaaaaaaaaaaaaaaaaaaa');
		} else {
			alert('nim0');
		}
		alert('Rezultat w handlecheck' + rezult); //2
	}
} 

function katal_add(vkatalog)
{
	if(ajax)
	{
 		ajax.open('post', 'ajax.php?s=katal_add');
		ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
 		ajax.send("nazwa=" + encodeURIComponent(vkatalog) + "&priv=1&haslo=");
 		ajax.onreadystatechange = handle_check3; 	
	}
} 

Alert(oznaczyłem go w komentarzu jedynką) już dobrze wyświetla informację o rezultacie - już podaje właściwą wartość. Lecz mam wrażenie, że dalsza część kodu się nie wykonuje. Alert numer 2 nie wyświetla się oraz nowe pole nie zostaje dodane do select'a ani nie wyświetlony jest alert 'nowa pozycja' czy też 'nim0'.

Pzdr

0

Podejrzewam, że błąd powoduje ta linijka:

document.nowy_kod_frm.katalog.options[document.nowy_kod_frm.katalog.options.length] = new Option(vkatalog, rezult, false, true);

Coś tu pewnie jest źle. Może ocument.nowy_kod_frm nie istnieje, albo document.nowy_kod_frm.katalog nie istnieje (to mi wygląda szczególnie podejrzanie). Może Option nie jest funkcją. Albo zmienna vkatalog nie istnieje. Nie bardzo mi się też podoba sposób manipulowania opcjami selecta. Radziłbym pobranie elementu select za pomocą standardowych funkcji DOM, takich jak getElementById (tak Ci będzie najłatwiej, choć ja nie przepadam za używaniem tylko tej funkcji i olewaniem innych). No i tablice mają funkcję składową push, więc jeśli katalog.options jest tablicą, to wystarczy zrobić:

katalog.options.push(nowa_opcja);

Btw., czym jest ten katalog? To jakiś Twój obiekt? Bo rozumiem, że Option to stworzony przez Ciebie konstruktor?

Tak w ogóle to jeśli mógłbyś dać linka do strony live, to wtedy mógłbym pomóc przy debugowaniu.

0

Już wiem o co biega. Funkcja katal_add() przyjmuje jako argument vkatalog, a w funkcji handle_check3 jest on nieznany. Tylko nie wiem w jaki sposób mogę zrobić, żeby w tej funkcji był on znany. Nie da się funkcji przekazać argumentu, więc nie wiem co mam czynić xD

0

Użyj domknięcia. Jednej z najpiękniejszych cech JavaScriptu. Polega to na tym, że gdy masz dwie funkcje tak, że jedna jest zdefiniowana w drugiej, to funkcja wewnętrzna ma dostęp do zmiennych funkcji zewnętrznej. To brzmi banalnie, ale jest ekstremalnie potężnym narzędziem.

Możesz użyć tego w połączeniu z możliwością utworzenia funkcji anonimowych (kolejna z kilku najlepszych cech JS). Jeśli handle_check3 używasz tylko raz, to w ogóle nie musisz jej nadawać nazwy. Powiedzmy, że KOD_HANDLE_CHECK to cały kod, który masz wewnątrz funkcji handle_check3, o tak:

function handle_check3()
{
  KOD_HANDLE_CHECK;
} 

Możesz więc go wyciąć i zlikwidować funkcję handle_check3 i zamiast odnosić się do handle_check3 w katalog_add, użyć funkcji anonimowej:

function katal_add(vkatalog)
{
        if(ajax)
        {
                 ajax.open('post', 'ajax.php?s=katal_add');
                 ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                 ajax.send("nazwa=" + encodeURIComponent(vkatalog) + "&priv=1&haslo=");
                 ajax.onreadystatechange = function() { // do onreadystatechange podstawiamy funk. anonimową, bez nazwy
                   KOD_HANDLE_CHECK;
                 };
        }
}

A jeśli nie chcesz tak wstawiać jednego w drugie i chcesz zachować funkcję handle_check3, to zrób tak (używając anonimowej funkcji opakowującej w której -- dzięki domknięciu -- zmienna vkatalog jest widoczna i możemy ją przekazać jako parametr do handle_check3):

function handle_check3(vkatalog) // teraz i ona pobiera parametr vkatalog
{
  KOD_HANDLE_CHECK;
} 

function katal_add(vkatalog)
{
        if(ajax)
        {
                 ajax.open('post', 'ajax.php?s=katal_add');
                 ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                 ajax.send("nazwa=" + encodeURIComponent(vkatalog) + "&priv=1&haslo=");
                 ajax.onreadystatechange = function() { // do onreadystatechange podstawiamy funk. anonimową, bez nazwy
                   handle_check3(vkatalog); // przekazujemy handle_check3 parametr katalog
                 };
        }
}


0

Respect. Wszystko działa. Wielkie dzięki za pomoc.

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