jQuery i JSON pobieranie tablicy

0

Witam,
działam w jQuery i w momencie pobierania danych (ajax) w php robię tak:

$result = array('response' => $response, 'error' => $error);
echo json_encode($result);

Dzięki czemu w jQuery pobieram informacje jako:

data.response i data.error

To jest proste, ale jak chcę przekazać całą tablicę np:

$tab = array("a" => "b", "c" => "d");
$result = array('response' => $tab, 'error' => $error);
echo json_encode($result);

To wiem że jak wyświetlę data.response.a to pokaże się b, natomiast jak policzyć wielkość tablicy i jak ją wrzucić w pętlę.

Chcę po prosu pobierać całość na zasadzie:

foreach(data.response as id => ele)
{

}

ale w jQuery (JavaScript)

0

for(var ele in data.response)

ew.:
data.response.forEach(function(ele, id) {
//...
});

0

Właśnie miałem napisać że problem rozwiązany. Zrobiłem tak:

for(var elem in data.response)
{
alert(elem + " - " + data.response[elem]);
}
1

@Coldpeer:
@Zi00mal:
Uściślijmy przechodzenie po obiektach/tablicach w JavaScripcie. Funkcji .forEach() i pętli for..in nie wolno -- a czasem się wręcz nie da -- stosować zamiennie.

Tablice to specjalne obiekty, które przechowują swoje elementy pod kluczami będącymi kolejnymi indeksami od 0 do tablica.length - 1. Np. tablica złożona z trzech stringów i jednej liczby: ["ala", "ma", "kota", 123]. Ogólnie, w JavaScripcie, tablice mogą mieć też klucze inne niż indeksy, ale nie w JSON-ie.

Obiekty można nazwać od biedy czymś w rodzaju hashmap lub tablic asocjacyjnych z PHP. Obiekty mapują klucze (będące ciągami znaków) na wartości, np. { response: "Jakiś tekst", error: 123 } (JSON wymaga, by klucze zawsze były otoczone cudzysłowami, ale w JS-ie zwykle można je pominąć).

I teraz: tablice mają metodę .forEach(), o której wspomniał @Coldpeer . To poprawna metoda iteracji po tablicy, choć jest niestety wolniejsza od klasycznej pętli for:

for (var i = 0; i < tablica.length; i++) { 
  ...
}

Szybkość iteracji jednak rzadko ma znaczenie.

Problem w tym, że obiekty nie mają metody .forEach() -- jest ona obecna tylko na tablicach. Więc w przypadku tablic asocjacyjnych z PHP, które są zapewne serializowane jako obiekty JSON, mielibyśmy problem. Przeglądarka powiedziałaby, że data.response.forEach to nie funkcja (tylko undefined).

Obiekty możemy przechodzić pętlą for..in, przy czym zmiennej sterującej nie nazwałbym elem, bo sugeruje to element (wartość elementu), a zmienna sterująca w pętli for to klucz. Nazwałbym ją więc raczej key czy propertyName (skrótowo: prop).

Używając pętli for..in, praktycznie zawsze powinniśmy się zabezpieczyć przed własnościami odziedziczonymi z prototypu Object.prototype. Wszystkie obiekty w JavaScripcie dziedziczą kilka własności standardowych z Object.prototype. Normalnie nie stanowi to problemu, bo własności standardowe mają flagę [[Enumerable]] ustawioną na false, a to oznacza, że nie pokazują się w pętli for..in. Ale jeśli ktoś zrobi nieostrożnie np. tak:

Object.prototype.cośtam = function() {
 // ...
};

to własność cośtam będzie miała [[Enumerable]] ustawione na true i pojawi się w pętli for..in takiej jak ta, którą napisałeś. Bo Twój obiekt data.response odziedziczy własność cośtam po prototypie obiektu, mimo że tego nie chciałeś.

Dlatego w każdej iteracji pętli warto sprawdzić, czy dana właściwość jest tzw. "właściwością własną" (po angielsku lepiej brzmi: own property) danego obiektu (w przeciwnym wypadku wzięła się stąd, że została odziedziczona).

Zabezpieczona pętla wygląda tak:

var response = data.response; // żeby się nie powtarzać
for (var key in response) {
  if (response.hasOwnProperty(key)) {
    alert(key + " - " + response[key]);
  }
}

Ciekawskim powiem, że i to nie jest stuprocentowe zabezpieczenie, bo wykrzaczy się, jeśli jakiś dowcipniś wstawi nam do response właściwość o kluczu... hasOwnProperty :-). Po stronie klienta nie musimy się tym przejmować, ale dla wielu serwerów z NodeJS-a był to problem, który trzeba było sprytnie obchodzić.

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