Ich versuche einige Dinge in Angular 2 Alpha 28 zu tun und habe ein Problem mit Wörterbüchern und NgFor.
Ich habe eine Oberfläche in TypeScript, die so aussieht:
interface Dictionary {
[ index: string ]: string
}
In JavaScript wird dies in ein Objekt übersetzt, das mit Daten folgendermaßen aussehen könnte:
myDict={'key1':'value1','key2':'value2'}
Ich möchte darüber iterieren und habe Folgendes versucht:
<div *ngFor="(#key, #value) of myDict">{{key}}:{{value}}</div>
Aber ohne Erfolg funktionierte auch keiner der folgenden Punkte:
<div *ngFor="#value of myDict">{{value}}</div>
<div *ngFor="#value of myDict #key=index">{{key}}:{{value}}</div>
In allen Fällen erhalte ich Fehler wie "Unerwartetes Token" oder "IterableDiff-Pipe-unterstützendes Objekt kann nicht gefunden werden".
Was vermisse ich hier? Ist das nicht mehr möglich? (Die erste Syntax funktioniert in Angular 1.x) oder unterscheidet sich die Syntax für die Iteration über ein Objekt?
Antworten:
Es scheint, dass sie die Syntax von ng1 nicht unterstützen wollen.
Nach Miško Hevery ( Referenz ):
Um über Ihr Objekt zu iterieren, müssen Sie eine "Pipe" verwenden. Derzeit ist keine Pipe implementiert, die dies tut.
Um dieses Problem zu umgehen, finden Sie hier ein kleines Beispiel, das die Schlüssel durchläuft:
Komponente:
quelle
key
alsnumber
undvalue
als,string
aber Winkel wirft Fehlerexpression has changed after it was checked
? warum so eine Idee?Angular 6.1.0+ Antwort
Verwenden Sie das eingebaute
keyvalue
Rohr wie folgt :oder so:
Wo
mySortingFunction
ist in Ihrer.ts
Datei zum Beispiel:Stackblitz: https://stackblitz.com/edit/angular-iterate-key-value
Sie müssen dies in keinem Modul registrieren, da Angular Pipes in jeder Vorlage sofort funktionieren.
Es funktioniert auch für Javascript-Maps .
quelle
implements PipeTransform
in der Klassendefinition hinzufügen (siehe angle.io/guide/pipes#custom-pipes )return Object.keys(dict).map(key => ({key, val: dict[key]}))
?versuche dieses Rohr zu benutzen
quelle
Neben der Antwort von @ obscur finden Sie hier ein Beispiel dafür, wie Sie sowohl auf das
key
als auchvalue
auf das @ View zugreifen können.Rohr:
Aussicht:
Wenn das Objekt also so aussehen würde:
Das generierte Ergebnis wäre:
Vorname: Daario
Nachname: Naharis
Vorname: Victarion
Nachname: Greyjoy
Vorname: Quentyn
Nachname: Ball
quelle
<li *ngFor="let u of myObject | keyValueFilter">First Name: {{u.key}} <br> Last Name: {{u.value}}</li>
. +1 von mir.return { 'key' : key, 'value' : value[key] };
Aktualisiert: Angular stellt jetzt die Pipe zum Durchlaufen des JSON-Objekts bereit über
keyvalue
:WORKING DEMO und für weitere Informationen lesen Sie
Zuvor (für ältere Versionen): Bis jetzt war die beste / kürzeste Antwort, die ich gefunden habe, (ohne Rohrfilter oder benutzerdefinierte Funktion von der Komponentenseite)
ARBEITSDEMO
quelle
let item of myDict | keyvalue
Das hat mein Problem gelöst.Hinzufügen zu SimonHawesome ' ausgezeichneter Antwort . Ich habe eine prägnante Version erstellt, die einige der neuen Typoskriptfunktionen verwendet. Mir ist klar, dass die Version von SimonHawesome absichtlich ausführlich ist, um die zugrunde liegenden Details zu erklären. Ich habe auch eine Early-Out-Prüfung hinzugefügt, damit die Pipe für falsche Werte funktioniert . ZB wenn die Karte ist
null
.Beachten Sie, dass die Verwendung einer Iterator-Transformation (wie hier ausgeführt) effizienter sein kann, da kein Speicher für ein temporäres Array zugewiesen werden muss (wie in einigen anderen Antworten beschrieben).
quelle
PipeTransform
Hier ist eine Variation einiger der oben genannten Antworten, die mehrere Transformationen (Schlüsselwert, Schlüssel, Wert) unterstützt:
Verwendung
quelle
pure: false
ist wirklich wichtig für sofortige Reflexionen.Ich hatte ein ähnliches Problem, baute etwas für Objekte und Karten.
quelle
implements PipeTransform
zur Klassendefinition hinzufügen solltenAngular 2.x && Angular 4.x unterstützen dies nicht sofort
Sie können diese beiden Pipes verwenden, um entweder nach Schlüssel oder nach Wert zu iterieren .
Schlüsselrohr:
Wertepipe:
Wie benutzt man:
quelle
Wenn sich jemand fragt, wie man mit mehrdimensionalen Objekten arbeitet, ist hier die Lösung.
Nehmen wir an, wir haben folgendes Objekt in Betrieb
Fügen Sie in der Komponente die folgende Funktion hinzu
Endlich im Blick folgen
quelle
Ich habe mir die Haare ausgerissen, als ich versucht habe, Daten zu analysieren und zu verwenden, die von einem JSON-Abfrage- / API-Aufruf zurückgegeben wurden. Ich bin mir nicht sicher, wo genau ich falsch gelaufen bin. Ich habe das Gefühl, dass ich die Antwort seit Tagen umkreise und verschiedene Fehlercodes wie:
"Kann 'iterableDiff'-Pipe-unterstützendes Objekt nicht finden"
"Generisches TYpe-Array erfordert ein oder mehrere Argumente"
JSON-Analysefehler und andere sicher
Ich gehe davon aus, dass ich gerade die falsche Kombination von Korrekturen hatte.
Hier ist eine kurze Zusammenfassung der Fallstricke und Dinge, nach denen gesucht werden muss.
Überprüfen Sie zunächst das Ergebnis Ihrer API-Aufrufe. Ihre Ergebnisse können in Form eines Objekts, eines Arrays oder eines Arrays von Objekten vorliegen.
Ich werde nicht zu viel darauf eingehen. Es reicht zu sagen, dass der ursprüngliche Fehler des OP, nicht iterierbar zu sein, im Allgemeinen dadurch verursacht wird, dass Sie versuchen, ein Objekt und kein Array zu iterieren.
Hier sind einige meiner Debugging-Ergebnisse, die Variablen sowohl von Arrays als auch von Objekten zeigen
Da wir unser JSON-Ergebnis im Allgemeinen iterieren möchten, müssen wir sicherstellen, dass es die Form eines Arrays hat. Ich habe zahlreiche Beispiele ausprobiert und vielleicht wusste ich, was ich jetzt weiß, einige davon würden tatsächlich funktionieren, aber der Ansatz, den ich gewählt habe, bestand darin, eine Pipe zu implementieren, und der Code, den ich verwendete, war der von t.888 gepostete
Ehrlich gesagt denke ich, eines der Dinge, die mich dazu gebracht haben, war das Fehlen einer Fehlerbehandlung, indem ich den Aufruf 'return undefined' hinzufügte, von dem ich glaube, dass wir jetzt zulassen, dass nicht erwartete Daten an die Pipe gesendet werden, was offensichtlich in meinem Fall vorkam .
Wenn Sie sich nicht mit Argumenten für die Pipe befassen möchten (und ich denke, dass dies in den meisten Fällen nicht notwendig ist), können Sie einfach Folgendes zurückgeben
Einige Hinweise zum Erstellen Ihrer Pipe und Seite oder Komponente, die diese Pipe verwendet
Ich habe Fehler erhalten, dass 'name_of_my_pipe' nicht gefunden wurde
Verwenden Sie den Befehl 'ionic generate pipe' von der CLI, um sicherzustellen, dass die Rohrmodule.ts korrekt erstellt und referenziert werden. Stellen Sie sicher, dass Sie der Seite mypage.module.ts Folgendes hinzufügen.
(Sie sind sich nicht sicher, ob sich dies ändert, wenn Sie auch über ein eigenes custom_module verfügen. Möglicherweise müssen Sie es auch zur custommodule.module.ts hinzufügen.)
Wenn Sie den Befehl 'ionic generate page' verwendet haben, um Ihre Seite zu erstellen, diese Seite jedoch als Hauptseite verwenden möchten, denken Sie daran, den Seitenverweis aus app.module.ts zu entfernen (hier ist eine weitere Antwort, die ich dazu veröffentlicht habe https : / /forum.ionicframework.com/t/solved-pipe-not-found-in-custom-component/95179/13?u=dreaser
Bei meiner Suche nach Antworten gab es eine Reihe von Möglichkeiten, die Daten in der HTML-Datei anzuzeigen, und ich verstehe nicht genug, um die Unterschiede zu erklären. In bestimmten Szenarien ist es möglicherweise besser, sie übereinander zu verwenden.
Was jedoch funktionierte, das es mir ermöglichte, sowohl den Wert als auch den Schlüssel anzuzeigen, war Folgendes:
Um den API-Aufruf durchzuführen, müssen Sie HttpModule in app.module.ts importieren
und Sie benötigen HTTP auf der Seite, von der aus Sie den Anruf tätigen
Wenn Sie den API-Aufruf ausführen, scheinen Sie in der Lage zu sein, auf zwei verschiedene Arten auf die untergeordneten Daten (die Objekte oder Arrays innerhalb des Arrays) zuzugreifen. Beide scheinen zu funktionieren
entweder während des Anrufs
oder wenn Sie die Daten Ihrer lokalen Variablen zuweisen
(Ich bin mir nicht sicher, ob diese Variable ein Array-String sein muss, aber das ist es, was ich jetzt habe. Es kann als allgemeinere Variable funktionieren.)
Und zum Schluss war es nicht notwendig, die eingebaute JSON-Bibliothek zu verwenden. Diese beiden Aufrufe können jedoch nützlich sein, um von einem Objekt in einen String zu konvertieren und umgekehrt
Ich hoffe, diese Zusammenstellung von Informationen hilft jemandem.
quelle
quelle
Schnittstellen in TypeScript sind ein Entwicklungszeitkonstrukt (nur zum Werkzeugieren ... 0 Auswirkungen auf die Laufzeit). Sie sollten dasselbe TypeScript wie Ihr JavaScript schreiben.
quelle
Das Wörterbuch ist ein Objekt, kein Array. Ich glaube, ng-repeat erfordert ein Array in Angular 2.
Die einfachste Lösung wäre, eine Pipe / einen Filter zu erstellen, die das Objekt im laufenden Betrieb in ein Array konvertiert. Das heißt, Sie möchten wahrscheinlich ein Array verwenden, wie @basarat sagt.
quelle
Wenn Sie
es6-shim
oder Ihrtsconfig.json
Ziel habenes6
, können Sie ES6 Map verwenden , um es zu erstellen .quelle
Definieren Sie die
MapValuesPipe
und implementieren Sie PipeTransform :Fügen Sie Ihr Rohr in Ihr Rohrmodul ein. Dies ist wichtig, wenn Sie dasselbe Rohr in mehr als einer Komponente verwenden müssen :
Dann verwenden Sie einfach die Pipe in Ihrem HTML mit
*ngFor
:<tr *ngFor="let attribute of mMap | mapValuesPipe">
Denken Sie daran, dass Sie Ihr PipesModule in der Komponente deklarieren müssen, in der Sie die Pipe verwenden möchten:
quelle
Also wollte ich meine eigene Hilfsfunktion, objLength (obj), implementieren, die nur Object (obj) .keys.length zurückgibt. Als ich es dann zu meiner template * ngIf-Funktion hinzufügte, schlug meine IDE objectKeys () vor. Ich habe es versucht und es hat funktioniert. Nach seiner Deklaration scheint es von lib.es5.d.ts angeboten zu werden, also los geht's!
So habe ich es implementiert (ich habe ein benutzerdefiniertes Objekt, das serverseitig generierte Schlüssel als Index für Dateien verwendet, die ich hochgeladen habe):
quelle