2013-05-12 15 views
13

Mam strukturę tak:iterację mapą w javascript

var myMap = { 
    partnr1: ['modelA', 'modelB', 'modelC'], 
    partnr2: ['modelA', 'modelB', 'modelC'] 
}; 

będę iterację każdego z elementów (partnr) z ich associatives (modelach).

Staram podwójnym $ każdej iteracji, aby osiągnąć ten cel, ale nic się nie dzieje:

$.each(myMap, function (i, val) { 
    $.each(i, function (innerKey, innerValue) { 

     setTimeout(function() { 
      $('#variant').fadeOut("slow", function() { 
       $(this).text(innerKey + "-" + innerValue).fadeIn("slow"); 

      }); 

     }, i * 6000); 

    }); 
}); 

efekt za pomocą blaknięcie i obecnie, że staram się osiągnąć działa poprawnie przy użyciu pojedynczej wartości array (Object), ale nie wtedy, gdy potrzebuję więcej niż jedną wartość dla każdego klucza, jak tutaj.

Jakieś pomysły na to, jak przeprowadzić tę iterację z powodzeniem i czy istnieją inne sposoby niż wykorzystanie mapy, która byłaby lepsza w tym przypadku?

Wszelkie sugestie mogą być interesujące.

+0

To nie jest "mapa", ale "obiekt". –

Odpowiedz

3

Połączenie zwrotne z numerem $.each() przekazuje nazwę właściwości i wartość w tej kolejności. Dlatego próbujesz powtórzyć nazwy właściwości w wewnętrznym wywołaniu $.each(). Myślę, że chcesz:

$.each(myMap, function (i, val) { 
    $.each(val, function(innerKey, innerValue) { 
    // ... 
    }); 
}); 

W pętli wewnętrznej, podanej jako obiekt, np. Mapa, wartości są tablicami. To jest w porządku, ale pamiętaj, że wartości "innerKey" będą liczbami.

edit — Teraz kiedyś, że jest prostowane, oto kolejny problem:

setTimeout(function() { 

     // ... 

    }, i * 6000); 

Po raz pierwszy dzięki tej pętli "i" będzie ciąg "partnr1". Tak więc, ta próba mnożenia będzie skutkować NaN. Można zachować zewnętrzny licznik śledzić liczenia własności zewnętrznej mapie:

var pcount = 1; 
$.each(myMap, function(i, val) { 
    $.each(val, function(innerKey, innerValue) { 
    setTimeout(function() { 
     // ... 
    }, pcount++ * 6000); 
    }); 
}); 
+0

Dziękuję za odpowiedź. Zmieniając $ .each (i ... do $ .each (val .. mój kod powyżej działa w taki sposób, że pokazuje wynik, ale niestety tylko pokazuje ostatni wynik z mapy, więc przeskakuje prosto do końcowa iteracja – user2374903

+0

@ user2374903 nie, nie przeskakuje do ostatniego, chociaż wygląda na to, że nie patrzyłem dokładnie na wywołanie "setTimeout", więc dodam do mojej odpowiedzi – Pointy

+0

Zmieniając pcount od 1 do 0 (co oznacza, że ​​zaczyna się od pierwszej pętli), kod zadziałał, ale tylko pokazując modele jeden po drugim.Mój błąd polegający na tym, że tego nie wyjaśnię, polega na tym, aby wszystkie modele odpowiadające numerowi pokazanemu jako lista zostały wyblakłe. – user2374903

24

będę używać standardowych javascript:

for (var m in myMap){ 
    for (var i=0;i<myMap[m].length;i++){ 
    ... do something with myMap[m][i] ... 
    } 
} 

Uwaga różne sposoby leczenia obiektów i tablic.

+1

Dlaczego? I pominąłeś niezbędne zamknięcie ... – Bergi

+0

Jest szybszy i moim zdaniem czystszy. A ja pominąłem resztę, ponieważ nie jest dla mnie jasne, co ma robić. Co to jest #variant? Co powinien zrobić #variant? – Atle

+0

#variant jest identyfikatorem elementu div, który zostanie pokazany (wyblaknięty) informacją z mapy. Dla każdego partnr należy wyblaknąć na liście z odpowiednimi modelami. – user2374903

1

Do tego celu nie należy używać iteratorów. Zachowaj własną pętlę, zwiększając licznik w wywołaniu zwrotnym i rekurencyjnie wywołując operację na następnym elemencie.

$.each(myMap, function(_, arr) { 
    processArray(arr, 0); 
}); 

function processArray(arr, i) { 
    if (i >= arr.length) return; 

    setTimeout(function() { 
     $('#variant').fadeOut("slow", function() { 
      $(this).text(i + "-" + arr[i]).fadeIn("slow"); 

      // Handle next iteration 
      processArray(arr, ++i); 
     }); 
    }, 6000); 
} 

Choć nie jest to błąd logiczny w kodzie. Ustawiasz ten sam kontener na więcej niż jedną inną wartość w (mniej więcej) tym samym czasie. Być może masz na myśli, aby każdy z nich zaktualizował swój własny kontener.

+0

Dziękuję za sugestię. Próbowałem już kodu, ale masz rację, że jest problem z kontenerem. Poniższy kod działa jednak, ale tutaj jest tylko jedna tablica wartości: – user2374903

+0

To wygląda na miły sposób to zrobić. – Pointy

+0

$ .each (jArray, funkcja (i, val) { setTimeout (function() { $ ('# reklame2'). FadeOut ("slow", function() { $ (this) .text (val) .fadeIn ("slow"); \t \t \t \t \t}); \t \t \t \t \t $ { $ (this) .text (Val ('# reklame17') Fadeout ("wolno", function().) .fadeIn ("slow"); \t \t \t \t \t }); }, i * 6000); \t \t \t }); – user2374903