Próbuję zrobić kilka rzeczy w Angular 2 Alpha 28 i mam problem ze słownikami i NgFor.
Mam interfejs w TypeScript wyglądający tak:
interface Dictionary {
[ index: string ]: string
}
W JavaScript przełoży się to na obiekt, który z danymi może wyglądać tak:
myDict={'key1':'value1','key2':'value2'}
Chcę to powtórzyć i wypróbowałem to:
<div *ngFor="(#key, #value) of myDict">{{key}}:{{value}}</div>
Ale bezskutecznie, żadne z poniższych też nie zadziałało:
<div *ngFor="#value of myDict">{{value}}</div>
<div *ngFor="#value of myDict #key=index">{{key}}:{{value}}</div>
We wszystkich przypadkach pojawiają się błędy, takie jak „Nieoczekiwany token” lub „Nie można znaleźć obiektu obsługującego potok„ iterableDiff ””
Czego tu brakuje? Czy to już nie jest możliwe? (Pierwsza składnia działa w Angular 1.x) czy składnia jest inna w przypadku iteracji po obiekcie?
Odpowiedzi:
Wygląda na to, że nie chcą obsługiwać składni z ng1.
Według Miško Hevery ( odniesienie ):
Aby więc iterować po obiekcie, będziesz musiał użyć „potoku”. Obecnie nie ma zaimplementowanego potoku, który to robi.
Aby obejść ten problem, oto mały przykład, który iteruje po klawiszach:
Składnik:
źródło
key
jaknumber
ivalue
jak,string
ale kątowy rzuca błądexpression has changed after it was checked
? skąd taki pomysł?Odpowiedź Angular 6.1.0+
Użyj wbudowanej
keyvalue
rury w następujący sposób:lub tak:
gdzie
mySortingFunction
jest w twoim.ts
pliku, na przykład:Stackblitz: https://stackblitz.com/edit/angular-iterate-key-value
Nie musisz tego rejestrować w żadnym module, ponieważ rury kątowe działają po wyjęciu z pudełka w każdym szablonie.
Działa również z mapami Javascript .
źródło
implements PipeTransform
w definicji klasy (patrz angular.io/guide/pipes#custom-pipes )return Object.keys(dict).map(key => ({key, val: dict[key]}))
?spróbuj użyć tej rury
źródło
Oprócz odpowiedzi @ obscur, oto przykład, w jaki sposób można uzyskać dostęp zarówno do, jak
key
ivalue
z @View.Rura:
Widok:
Gdyby więc obiekt miał wyglądać tak:
Wygenerowany wynik byłby:
Imię: Daario
Nazwisko: Naharis
Imię: Victarion
Nazwisko: Greyjoy
Imię: Quentyn
Nazwisko: Ball
źródło
<li *ngFor="let u of myObject | keyValueFilter">First Name: {{u.key}} <br> Last Name: {{u.value}}</li>
. +1 ode mnie.return { 'key' : key, 'value' : value[key] };
Zaktualizowano: Angular zapewnia teraz rurkę do przecinania obiektu json za pośrednictwem
keyvalue
:PRACA DEMO i więcej szczegółów Przeczytaj
Wcześniej (dla starszej wersji): Do tej pory najlepszą / najkrótszą odpowiedzią, jaką znalazłem, jest (bez żadnego filtra rury lub funkcji niestandardowej po stronie komponentu)
PRACA DEMO
źródło
let item of myDict | keyvalue
to rozwiązało mój problem.Dodając do doskonałej odpowiedzi SimonHawesome . Stworzyłem zwięzłą wersję, która wykorzystuje niektóre z nowych funkcji maszynopisu. Zdaję sobie sprawę, że wersja SimonHawesome jest celowo rozwlekła, aby wyjaśnić podstawowe szczegóły. Dodałem również wczesne sprawdzenie, aby potok działał dla fałszywych wartości. Np. Jeśli mapa jest
null
.Zauważ, że użycie transformacji iteratora (tak jak tutaj) może być bardziej wydajne, ponieważ nie musimy przydzielać pamięci na tymczasową tablicę (jak to zrobiono w niektórych innych odpowiedziach).
źródło
PipeTransform
Oto odmiana niektórych z powyższych odpowiedzi, która obsługuje wiele przekształceń (wartość klucza, klucz, wartość):
Stosowanie
źródło
pure: false
jest naprawdę ważny dla natychmiastowych refleksji.Miałem podobny problem, zbudowałem coś dla obiektów i map.
źródło
implements PipeTransform
do definicji klasyAngular 2.x i Angular 4.x nie obsługują tego po wyjęciu z pudełka
Możesz użyć tych dwóch potoków do iteracji według klucza lub wartości .
Klucze rurowe:
Rura wartości:
Jak używać:
źródło
Jeśli ktoś się zastanawia, jak pracować z wielowymiarowym obiektem, oto rozwiązanie.
załóżmy, że mamy następujący obiekt w serwisie
w komponencie dodaj następującą funkcję
wreszcie w celu wykonania
źródło
Wyrywałem sobie włosy, próbując przeanalizować i wykorzystać dane zwrócone z zapytania JSON / wywołania API. Nie jestem pewien, dokąd poszedłem źle, czuję, że krążyłem odpowiedź od dni, ścigając różne kody błędów, takie jak:
„Nie można znaleźć obiektu obsługującego potok„ iterableDiff ””
„Ogólna tablica typu wymaga jednego argumentu (ów)”
Błędy analizy JSON i jestem pewien, że inni
Zakładam, że po prostu miałem niewłaściwą kombinację poprawek.
Oto krótkie podsumowanie problemów i rzeczy, na które należy zwrócić uwagę.
Najpierw sprawdź wynik wywołań interfejsu API, wyniki mogą mieć postać obiektu, tablicy lub tablicy obiektów.
nie będę się w to zbytnio zagłębiał, wystarczy powiedzieć, że pierwotny błąd OP, że nie jest iterowalny, jest generalnie spowodowany próbą iteracji obiektu, a nie tablicy.
Oto niektóre z moich wyników debugowania pokazujących zmienne zarówno tablic, jak i obiektów
Ponieważ generalnie chcielibyśmy iterować nasz wynik JSON, musimy upewnić się, że ma on postać tablicy. Wypróbowałem wiele przykładów i być może wiedząc, co teraz wiem, niektóre z nich faktycznie zadziałałyby, ale podejście, które zastosowałem, polegało na zaimplementowaniu potoku, a kod, którego użyłem, był taki, że opublikowany przez t.888
Szczerze mówiąc, myślę, że jedną z rzeczy, które mnie dopadły, był brak obsługi błędów, dodając wywołanie `` return undefined ''. Myślę, że teraz pozwalamy na wysyłanie niespodziewanych danych do potoku, co oczywiście miało miejsce w moim przypadku .
jeśli nie chcesz zajmować się argumentem do potoku (i nie sądzę, że jest to konieczne w większości przypadków), możesz po prostu zwrócić następujące polecenie
Kilka uwag na temat tworzenia rury i strony lub komponentu używającego tej rury
czy otrzymywałem błędy dotyczące nie znalezienia „name_of_my_pipe”
Użyj polecenia „ionic generowanie potoku” w interfejsie wiersza polecenia, aby upewnić się, że moduły potokowe. upewnij się, że dodałeś następujące elementy do strony mypage.module.ts.
(nie jestem pewien, czy to się zmieni, jeśli masz również własny moduł niestandardowy, może być konieczne dodanie go do custommodule.module.ts)
jeśli użyłeś polecenia „jonowa generuj stronę”, aby utworzyć swoją stronę, ale zdecydujesz się użyć tej strony jako strony głównej, pamiętaj, aby usunąć odwołanie do strony z app.module.ts (oto kolejna odpowiedź, którą opublikowałem, dotyczącą tego https: / /forum.ionicframework.com/t/solved-pipe-not-found-in-custom-component/95179/13?u=dreaser
W moich poszukiwaniach odpowiedzi, gdzie jest wiele sposobów wyświetlania danych w pliku html i nie rozumiem wystarczająco, aby wyjaśnić różnice. W niektórych scenariuszach może się okazać, że lepiej jest używać jednego nad drugim.
Jednak to, co zadziałało, pozwoliło mi wyświetlić zarówno wartość, jak i klucz, było następujące:
aby wywołać API, wygląda na to, że musisz zaimportować HttpModule do app.module.ts
i potrzebujesz Http na stronie, z której dzwonisz
Podczas wykonywania wywołania API wydaje się, że jesteś w stanie dostać się do danych podrzędnych (obiektów lub tablic w tablicy) na 2 różne sposoby, które wydają się działać
albo podczas rozmowy
lub kiedy przypisujesz dane do zmiennej lokalnej
(nie jestem pewien, czy ta zmienna musi być ciągiem tablicy, ale to jest to, co mam teraz. Może działać jako zmienna bardziej ogólna)
I ostatnia uwaga, nie było konieczne korzystanie z wbudowanej biblioteki JSON, jednak te 2 wywołania mogą być przydatne do konwersji z obiektu na ciąg i odwrotnie
Mam nadzieję, że ta kompilacja informacji komuś pomoże.
źródło
źródło
Interfejsy w języku TypeScript są konstrukcjami deweloperskimi (wyłącznie dla narzędzi ... 0 wpływu na środowisko wykonawcze). Powinieneś napisać ten sam TypeScript, co JavaScript.
źródło
Słownik jest obiektem, a nie tablicą. Uważam, że ng-repeat wymaga tablicy w Angular 2.
Najprostszym rozwiązaniem byłoby utworzenie potoku / filtra, który przekształca obiekt w tablicę w locie. To powiedziawszy, prawdopodobnie chcesz użyć tablicy, jak mówi @basarat.
źródło
Jeśli masz
es6-shim
lub twójtsconfig.json
celes6
, możesz użyć mapy ES6, aby to zrobić.źródło
Zdefiniuj
MapValuesPipe
i zaimplementuj PipeTransform :Dodaj rurę do modułu rur. Jest to ważne, jeśli musisz użyć tej samej rury w więcej niż jednym komponencie :
Następnie po prostu użyj potoku w swoim html z
*ngFor
:<tr *ngFor="let attribute of mMap | mapValuesPipe">
Pamiętaj, że będziesz musiał zadeklarować swój PipesModule w komponencie, w którym chcesz użyć potoku:
źródło
Zamierzałem więc zaimplementować własną funkcję pomocniczą, objLength (obj), która zwraca po prostu Object (obj) .keys.length. Ale kiedy dodawałem go do funkcji szablonu * ngIf, moje IDE zasugerowało obiektKeys (). Spróbowałem i zadziałało. Zgodnie z deklaracją wydaje się, że jest oferowany przez lib.es5.d.ts, więc proszę bardzo!
Oto jak to zaimplementowałem (mam niestandardowy obiekt, który używa kluczy wygenerowanych po stronie serwera jako indeksu dla przesłanych plików):
źródło