Jak używać powtórzeń ng do słowników w AngularJs?

285

Wiem, że możemy łatwo używać powtórzenia ng dla obiektów Json lub tablic takich jak:

<div ng-repeat="user in users"></div>

ale jak możemy użyć powtórzenia ng do słowników, na przykład:

var users = null;
users["182982"] = "{...json-object...}";
users["198784"] = "{...json-object...}";
users["119827"] = "{...json-object...}";

Chcę tego używać ze słownikiem użytkowników:

<div ng-repeat="user in users"></div>

Czy to możliwe?. Jeśli tak, jak mogę to zrobić w AngularJs?

Przykład mojego pytania: W języku C # definiujemy słowniki takie jak:

Dictionary<key,value> dict = new Dictionary<key,value>();

//and then we can search for values, without knowing the keys
foreach(var val in dict.Values)
{
}

Czy jest wbudowana funkcja, która zwraca wartości ze słownika, jak w c #?

Vural
źródło
1
Jaka jest różnica między słownikiem a obiektem JSON? Wierzę, że nie ma w javascript!
markmarijnissen
8
@markmarijnissen: Obiekt JSON ma bardziej rygorystyczne reguły składniowe niż obiekt JavaScript . A ponieważ jesteśmy już w Pedant's Corner, nie ma czegoś takiego jak „Słownik” w JavaScript. Nazywamy je po prostu przedmiotami.
Paul D. Waite

Odpowiedzi:

556

Możesz użyć

<li ng-repeat="(name, age) in items">{{name}}: {{age}}</li>

Zobacz dokumentację ngRepeat . Przykład: http://jsfiddle.net/WRtqV/1/

Artem Andreev
źródło
53
Nie o to prosiłem, ale dokładnie tego, czego chciałem. Dziękuję Artem Andreev
Vural
1
Jak możemy użyć filtra w tym powtórzeniu ng. Nie działa w moim przypadku, gdy korzystam z filtra wyszukiwania. Powiedz <input type = "text" ng-model = "searchText" /> <li ng-repeat = "(imię, wiek) w elementach | filter: searchText"> {{name}}: {{age}} </ li> ...
Shekhar
1
@Shekhar Filtr „filtr” działa tylko z tablicami. Możesz spróbować utworzyć żądanie funkcji.
Artem Andreev
2
Dobrze widzieć trochę podobieństwa do Pythona :)
Robert King
4
Możesz uzyskać funkcję filtrowania nawet w słownikach (obiektach), używając instrukcji ng-if .. jak na przykład: <li ng-repeat = "(id, obj) w elementach" ng-if = 'obj.sex = "female "'> {{obj.name}} {{obj. nazwisko}} </li> ... gdzie item to zbiór osób indeksowanych według jakiegoś klucza.
giowild
27

Chciałbym również wspomnieć o nowej funkcjonalności AngularJSng-repeat , a mianowicie o specjalnych punktach początkowych i końcowych powtarzania . Ta funkcjonalność została dodana w celu powtórzenia serii elementów HTML zamiast tylko jednego rodzica elementu HTML.

Aby użyć punktów początkowych i końcowych repeatera, musisz zdefiniować je odpowiednio za pomocą ng-repeat-starti ng-repeat-enddyrektyw.

ng-repeat-startDyrektywa działa bardzo podobnie do ng-repeatdyrektywy. Różnica polega na tym, że powtórzy wszystkie elementy HTML (w tym znacznik, w którym jest zdefiniowany) aż do końcowego znacznika HTML, w którym ng-repeat-endjest umieszczony (w tym znacznik z ng-repeat-end).

Przykładowy kod (z kontrolera):

// ...
$scope.users = {};
$scope.users["182982"] = {name:"John", age: 30};
$scope.users["198784"] = {name:"Antonio", age: 32};
$scope.users["119827"] = {name:"Stephan", age: 18};
// ...

Przykładowy szablon HTML:

<div ng-repeat-start="(id, user) in users">
    ==== User details ====
</div>
<div>
    <span>{{$index+1}}. </span>
    <strong>{{id}} </strong>
    <span class="name">{{user.name}} </span>
    <span class="age">({{user.age}})</span>
</div>

<div ng-if="!$first">
   <img src="/some_image.jpg" alt="some img" title="some img" />
</div>
<div ng-repeat-end>
    ======================
</div>

Dane wyjściowe wyglądałyby podobnie do następujących (w zależności od stylu HTML):

==== User details ====
1.  119827 Stephan (18)
======================
==== User details ====
2.  182982 John (30)
[sample image goes here]
======================
==== User details ====
3.  198784 Antonio (32)
[sample image goes here]
======================

Jak widać, ng-repeat-startpowtarza wszystkie elementy HTML (w tym element z ng-repeat-start). Wszystkie ng-repeatspecjalne właściwości (w tym przypadku $firsti $index) działają również zgodnie z oczekiwaniami.

Tomek
źródło
Błąd: [$ compile: uterdir] Nieokreślony atrybut, znaleziono „ng-repeat-start”, ale nie znaleziono pasującego „ng-repeat-end”.
zloctb
@zloctb musiałeś pominąć <div ng-repeat-end>..</div>swój znacznik
John Kaster
6

Programiści JavaScript zwykle odnoszą się do powyższej struktury danych jako obiekt lub skrót zamiast Słownika.

Twoja powyższa składnia jest nieprawidłowa, ponieważ inicjujesz usersobiekt jako null. Zakładam, że jest to literówka, ponieważ kod powinien brzmieć:

// Initialize users as a new hash.
var users = {};
users["182982"] = "...";

Aby pobrać wszystkie wartości z skrótu, musisz iterować nad nim za pomocą pętli for:

function getValues (hash) {
    var values = [];
    for (var key in hash) {

        // Ensure that the `key` is actually a member of the hash and not
        // a member of the `prototype`.
        // see: http://javascript.crockford.com/code.html#for%20statement
        if (hash.hasOwnProperty(key)) {
            values.push(key);
        }
    }
    return values;
};

Jeśli planujesz dużo pracy ze strukturami danych w JavaScript, biblioteka underscore.js jest zdecydowanie warta obejrzenia. Podkreślenie zawiera valuesmetodę, która wykona dla ciebie powyższe zadanie:

var values = _.values(users);

Sam nie używam Angulara, ale jestem prawie pewien, że będzie wbudowana wygodna metoda do iteracji wartości hash (ach, proszę bardzo, Artem Andreev podaje odpowiedź powyżej :))

JonnyReeves
źródło
1
+1 za underscore.js i te przydatne informacje. Dziękuję Johnny!
Vural
0

W Angular 7 zadziałałby następujący prosty przykład (zakładając, że słownik znajduje się w zmiennej o nazwie d):

my.component.ts:

keys: string[] = [];  // declaration of class member 'keys'
// component code ...

this.keys = Object.keys(d);

my.component.html: (wyświetli listę par klucz: wartość)

<ul *ngFor="let key of keys">
    {{key}}: {{d[key]}}
</ul>
Ron Kalian
źródło