foreach loop w angularjs

110

Ja jechałem przez forEach loopIN AngularJS. Jest kilka punktów, których nie rozumiem.

  1. Jaki jest pożytek z funkcji iteratora? Czy można się bez niego obejść?
  2. Jakie jest znaczenie klucza i wartości, jak pokazano poniżej?

angular.forEach($scope.data, function(value, key){});

PS: Próbowałem uruchomić tę funkcję bez argumentów i nie działa.

Oto moje json:

[
   {
     "Name": "Thomas",
     "Password": "thomasTheKing"
   },
   {
     "Name": "Linda",
     "Password": "lindatheQueen"
   }
]

Mój JavaScriptplik:

var app = angular.module('testModule', []);

app.controller('testController', function($scope, $http){
   $http.get('Data/info.json').then(
      function(data){
         $scope.data = data;
      }
   );

   angular.forEach($scope.data, function(value, key){
      if(value.Password == "thomasTheKing")
         console.log("username is thomas");
   });
});

Kolejne pytanie : dlaczego powyższa funkcja nie włącza warunku warunkowego i wypisuje w konsoli "nazwa użytkownika to thomas"?

Pragam Shrivastava
źródło
6
Ponieważ nie czekasz, successaż to $http.get(), co się angular.forEach()wydarzy, $scope.datajest nadal nieokreślone.
Tom
1
Czy jest jakiś konkretny sposób na wstrzymanie wykonania kodu do czasu załadowania
pliku
Zmień linię na tę angular.forEach (wartości, funkcja (wartość, klucz) {console.log (klawisz + ':' + wartość.Nazwa);});
Israel Ocbina

Odpowiedzi:

208

Pytania 1 i 2

Zasadniczo pierwszym parametrem jest obiekt do iteracji. Może to być tablica lub obiekt. Jeśli jest to taki obiekt:

var values = {name: 'misko', gender: 'male'};

Angular przyjmie każdą wartość po kolei, pierwsza to nazwa, druga to płeć.

Jeśli twoim obiektem do iteracji jest tablica (również możliwa), na przykład:

[{ "Name" : "Thomas", "Password" : "thomasTheKing" },
 { "Name" : "Linda", "Password" : "lindatheQueen" }]

Angular.forEach będzie zajmować się pojedynczo, zaczynając od pierwszego obiektu, a następnie drugiego obiektu.

Dla każdego tego obiektu będzie więc pobierał je jeden po drugim i wykonywał określony kod dla każdej wartości. Ten kod jest nazywany funkcją iteratora . forEach jest inteligentny i zachowuje się inaczej, jeśli używasz tablicy kolekcji. Oto kilka przykładów:

var obj = {name: 'misko', gender: 'male'};
var log = [];
angular.forEach(obj, function(value, key) {
  console.log(key + ': ' + value);
});
// it will log two iteration like this
// name: misko
// gender: male

Więc klucz to ciąg znaków twojego klucza, a wartość to ... wartość. Możesz użyć klucza, aby uzyskać dostęp do swojej wartości w następujący sposób:obj['name'] = 'John'

Jeśli tym razem wyświetlisz tablicę, taką jak ta:

var values = [{ "Name" : "Thomas", "Password" : "thomasTheKing" },
           { "Name" : "Linda", "Password" : "lindatheQueen" }];
angular.forEach(values, function(value, key){
     console.log(key + ': ' + value);
});
// it will log two iteration like this
// 0: [object Object]
// 1: [object Object]

Zatem wartość to twój obiekt (kolekcja), a klucz to indeks twojej tablicy, ponieważ:

[{ "Name" : "Thomas", "Password" : "thomasTheKing" },
 { "Name" : "Linda", "Password" : "lindatheQueen" }]
// is equal to
{0: { "Name" : "Thomas", "Password" : "thomasTheKing" },
 1: { "Name" : "Linda", "Password" : "lindatheQueen" }}

Mam nadzieję, że to odpowiedź na twoje pytanie. Oto JSFiddle do uruchomienia kodu i przetestowania, jeśli chcesz: http://jsfiddle.net/ygahqdge/

Debugowanie kodu

Problem wydaje się wynikać z faktu, $http.get()że żądanie jest asynchroniczne.

Wysłać zapytanie o swojego syna, WTEDY , kiedy koniec przeglądarka pobierając go wykonywał sukces. ALE zaraz po wysłaniu zapytania wykonujesz pętlę, angular.forEachnie czekając na odpowiedź swojego JSON.

Musisz uwzględnić pętlę w funkcji sukcesu

var app = angular.module('testModule', [])
    .controller('testController', ['$scope', '$http', function($scope, $http){
    $http.get('Data/info.json').then(function(data){
         $scope.data = data;

         angular.forEach($scope.data, function(value, key){
         if(value.Password == "thomasTheKing")
           console.log("username is thomas");
         });
    });

});

To powinno działać.

Idąc głębiej

$ Http API jest oparty na odroczony / obiecują API odsłonięte przez serwis $ q. Podczas gdy w przypadku prostych wzorców użycia nie ma to większego znaczenia, w przypadku zaawansowanego użytkowania ważne jest, aby zapoznać się z tymi interfejsami API i gwarancjami, które zapewniają.

Możesz przyjrzeć się odroczonym / obiecanym interfejsom API . Ważną koncepcją Angular jest wykonywanie płynnych asynchronicznych akcji.

sebastienbarbier
źródło
2
Colin B (profil tutaj .) Chciał to skomentować successi error został wycofany . Sugeruje się użycie thenmetody zamiast success. Teraz @Colin, wyjdź i odpowiedz na kilka pytań, aby uzyskać 50 powtórzeń! : P
Drew
3
Async nie jest równoległy. Równolegle będzie potrzebował pracowników sieci, a nie obietnic. Trochę pedantyczny, ale warto powstrzymać dezinformację na ten temat, gdy tylko się zdarzy.
Kyle Baker
1
Dzięki @KyleBaker, zaktualizowałem tę odpowiedź, masz rację, „równoległość” była nadużyciem języka.
sebastienbarbier
@sebastienbarbier, czy możesz mi pomóc rozwiązać ten stackoverflow.com/questions/50100381/ ...
Nikson
7

musisz użyć zagnieżdżonych pętli angular.forEach dla JSON, jak pokazano poniżej:

 var values = [
        {
            "name":"Thomas",
            "password":"thomas"
        },
        { 
            "name":"linda",
            "password":"linda"
        }];

    angular.forEach(values,function(value,key){
        angular.forEach(value,function(v1,k1){//this is nested angular.forEach loop
            console.log(k1+":"+v1);
        });
    });
wiśnia
źródło
1
Nie, użyłbyś pojedynczej pętli i szczerze mówiąc, w tym przypadku powinieneś po prostu użyć natywnego forEach (), a la values.forEach(object => console.log($ {object.name}: $ {object.password} )).
Kyle Baker
Po prostu zmień wiersz console.log (klawisz + ':' + wartość); INTO console.log (klawisz + ':' + wartość.Nazwa);
Israel Ocbina
5

angular.forEach()Będzie iterację Twojego jsonobiektu.

Pierwsza iteracja,

klucz = 0, wartość = {"nazwa": "Tomasz", "hasło": "thomasTheKing"}

Druga iteracja,

klucz = 1, wartość = {"nazwa": "Linda", "hasło": "lindatheQueen"}

Aby uzyskać wartość swojego name, możesz użyć value.namelub value["name"]. To samo z twoim password, używasz value.passwordlub value["password"].

Poniższy kod da ci to, czego chcesz:

   angular.forEach(json, function (value, key)
         {
                //console.log(key);
                //console.log(value);
                if (value.password == "thomasTheKing") {
                    console.log("username is thomas");
                }
         });
nrs
źródło
2

Zmień linię na to

 angular.forEach(values, function(value, key){
   console.log(key + ': ' + value);
 });

 angular.forEach(values, function(value, key){
   console.log(key + ': ' + value.Name);
 });
Israel Ocbina
źródło
2

W Angular 7 pętla for wygląda jak poniżej

var values = [
        {
            "name":"Thomas",
            "password":"thomas"
        },
        { 
            "name":"linda",
            "password":"linda"
        }];

for (let item of values)
{
}
sajadre
źródło