Anscheinend wird Angular 2 Pipes anstelle von Filtern wie in Angular1 in Verbindung mit ng-for verwenden, um Ergebnisse zu filtern, obwohl die Implementierung noch vage zu sein scheint, ohne klare Dokumentation.
Was ich erreichen möchte, kann nämlich aus der folgenden Perspektive betrachtet werden
<div *ng-for="#item of itemsList" *ng-if="conditon(item)"></div>
Wie implementiere ich das mit Rohren?
angular
typescript
Khaled
quelle
quelle
<div *ngFor="let item of itemsList" *ngIf="conditon(item)" ...
*ngFor
und*ngIf
auf dem gleichen Element werden nicht unterstützt. Sie müssen zu der expliziten Form für eines von ihnen wechseln"Antworten:
Grundsätzlich schreiben Sie eine Pipe, die Sie dann in der
*ngFor
Direktive verwenden können.In Ihrer Komponente:
In Ihrer Vorlage können Sie eine Zeichenfolge, eine Nummer oder ein Objekt an Ihre Pipe übergeben, um nach folgenden Elementen zu filtern:
In deiner Pfeife:
Denken Sie daran, Ihre Pipe zu registrieren
app.module.ts
. Sie müssen die Rohre nicht mehr in Ihrem registrieren@Component
Hier ist ein Plunker, der die Verwendung eines benutzerdefinierten Filterrohrs und des integrierten Slice-Rohrs demonstriert , um die Ergebnisse zu begrenzen.
Bitte beachten Sie (wie mehrere Kommentatoren hervorgehoben haben), dass es einen Grund gibt, warum es in Angular keine eingebauten Filterrohre gibt.
quelle
*ngFor
Parameter in Klammern zu setzen, um Verwirrung zu vermeiden und sie "veränderungssicher" zu machen:<li *ngFor="let item of (items | myfilter:filterargs)">
Viele von Ihnen haben großartige Ansätze, aber das Ziel hier ist es, generisch zu sein und eine Array-Pipe zu definieren, die in Bezug auf * ngFor in allen Fällen extrem wiederverwendbar ist.
callback.pipe.ts (vergessen Sie nicht, dies dem Deklarationsarray Ihres Moduls hinzuzufügen)
Dann müssen Sie in Ihrer Komponente eine Methode mit der folgenden Signatur (item: any) => boolean implementieren. In meinem Fall habe ich sie beispielsweise filterUser genannt, um das Alter der Benutzer zu filtern, die größer als 18 Jahre sind.
Ihre Komponente
Und zu guter Letzt sieht Ihr HTML-Code folgendermaßen aus:
Ihr HTML
Wie Sie sehen können, ist diese Pipe für alle Array-ähnlichen Elemente, die über einen Rückruf gefiltert werden müssen, ziemlich allgemein. In meinem Fall fand ich es sehr nützlich für * ngFür ähnliche Szenarien.
Hoffe das hilft!!!
Codematrix
quelle
this
filterUser = (user: IUser) =>
filteruser(user: IUser)
this
bei Ihrer Komponentenmethode verloren haben, ist, dass die Methode als Rückruf verwendet wurde und ein neuerthis
Kontext angewendet wurde. Sie sind auf ein häufiges Problem in objektorientiertem Javascript gestoßen, aber es gibt eine alte und einfache Lösung: Sie binden Methoden, die als Rückrufe verwendet werden sollen, an die ursprüngliche Klasse. Fügen Sie in Ihrem Konstruktor den folgenden Code hinzu:this.myCallbackFunc = this.myCallbackFunc.bind(this);
Das war's. Du wirst niethis
wieder verlieren .Vereinfachte Methode (Wird aufgrund von Leistungsproblemen nur bei kleinen Arrays verwendet. Bei großen Arrays muss der Filter manuell per Code erstellt werden):
Siehe: https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe
Verwendungszweck:
Wenn Sie eine Variable als zweites Argument verwenden, verwenden Sie keine Anführungszeichen.
quelle
Dies ist, was ich ohne Verwendung von Pipe implementiert habe.
component.html
component.ts
quelle
itemList
ein Observable zu erstellen und den asynchronen Filter zu verwenden :let item of itemsList | async
. Wenn eine Änderung auftritt, lassen Sie das Observable die neue Liste ausgeben. Auf diese Weise wird der Filtercode nur bei Bedarf ausgeführt.Ich bin mir nicht sicher, wann es reinkam, aber sie haben bereits Slice Pipe gemacht, das das macht. Es ist auch gut dokumentiert.
https://angular.io/docs/ts/latest/api/common/index/SlicePipe-pipe.html
quelle
;
. zB:*ngFor="let feature of content?.keyFeatures | slice:1:5; trackBy feature?.id"
Sie können auch Folgendes verwenden:
Dies zeigt nur die Div an, wenn Ihre Artikel der Bedingung entsprechen
Siehe die Winkel Dokumentation für weitere Informationen Wenn Sie auch den Index benötigen würde, verwenden Sie die folgenden Schritte aus :
quelle
Pipes in Angular2 ähneln Pipes in der Befehlszeile. Die Ausgabe jedes vorhergehenden Werts wird nach dem Rohr in den Filter eingespeist, wodurch es einfach ist, Filter wie folgt zu verketten:
quelle
item
von*ng-for="#item of itemsList"
verwendet werden sollte, um die Ergebnisse als solche zu filtern*ng-if="conditon(item)"
. Was in diesem Beispiel nicht funktioniert ..item
wenn die Bedingung erfüllt ist, und keinen Wert, wenn dies nicht der Fall ist.*ngFor
und*ngIf
auf dem gleichen Element werden nicht unterstützt. Sie müssen zu der expliziten Form für einen von ihnen wechseln<template ngFor ...>
Für diese Anforderung implementiere und veröffentliche ich eine generische Komponente . Sehen
https://www.npmjs.com/package/w-ng5
Um diese Komponenten zu verwenden, installieren Sie dieses Paket zuvor mit npm:
Importieren Sie anschließend das Modul in app.module
Fügen Sie im nächsten Schritt den Deklarationsabschnitt von app.module hinzu:
Verwendung der Probe
Einfache Zeichenfolge filtern
Filterung komplexer Zeichenfolgen - Feld 'Wert' in Ebene 2
Filterung komplexer Zeichenfolgen - mittleres Feld - 'Wert' in Ebene 1
Einfaches Filtern komplexer Arrays - Feld 'Nome' Level 0
Filtern in Baumfeldern - Feld 'Tapferkeit' in Stufe 2 oder 'Tapferkeit' in Stufe 1 oder 'Nome' in Stufe 0
Nicht vorhandenes Feld filtern - 'Tapferkeit' in nicht vorhandenem Level 3
Diese Komponente arbeitet mit einer unendlichen Attributebene ...
quelle
*ngFor="let inovice of invoices | filter:searchInvoice"
und es wird auf meiner Liste gesucht, aber es wird eine leere Liste angezeigt. Weißt du warum?Eine einfache Lösung, die mit Angular 6 zum Filtern eines ngFor zusammenarbeitet, ist die folgende:
Spannweiten sind nützlich, da sie von Natur aus nichts darstellen.
quelle
Ich weiß, dass es eine alte Frage ist, aber ich dachte, es könnte hilfreich sein, eine andere Lösung anzubieten.
Äquivalent von AngularJS davon
In Angular 2+ können Sie * ngFor und * ngIf nicht für dasselbe Element verwenden.
und wenn Sie nicht als internen Container verwenden können, verwenden Sie stattdessen ng-container. ng-container ist nützlich, wenn Sie eine Gruppe von Elementen (dh mit * ngIf = "foo") in Ihrer Anwendung bedingt anhängen möchten, diese aber nicht mit einem anderen Element umschließen möchten.
quelle
Ich habe einen Plunker erstellt, der auf den Antworten hier und anderswo basiert.
Zusätzlich musste ich ein
@Input
,@ViewChild
undElementRef
von<input>
und erstellen undsubscribe()
ein beobachtbares davon erstellen .Angular2-Suchfilter: PLUNKR (UPDATE: Plunker funktioniert nicht mehr)
quelle
Rohr wäre der beste Ansatz. aber unten würde man auch funktionieren.
quelle
Das ist mein Code:
Stichprobe:
quelle
Ein anderer Ansatz, den ich gerne für anwendungsspezifische Filter verwende, ist die Verwendung einer benutzerdefinierten schreibgeschützten Eigenschaft für Ihre Komponente, mit der Sie die Filterlogik sauberer kapseln können als mit einer benutzerdefinierten Pipe (IMHO).
Zum Beispiel, wenn ich binden
albumList
und filtern möchtesearchText
:Um im HTML zu binden, können Sie dann an die schreibgeschützte Eigenschaft binden:
Ich finde, dass für spezielle Filter, die anwendungsspezifisch sind, dies besser funktioniert als eine Pipe, da die Logik in Bezug auf den Filter mit der Komponente beibehalten wird.
Rohre funktionieren besser für global wiederverwendbare Filter.
quelle
Ich habe die folgende Pipe erstellt, um die gewünschten Elemente aus einer Liste abzurufen.
Die Konvertierung in Kleinbuchstaben entspricht nur der Groß- und Kleinschreibung. Sie können es in Ihrer Ansicht folgendermaßen verwenden: -
quelle
Idealerweise sollten Sie dafür ein Angualr 2-Rohr erstellen. Aber du kannst diesen Trick machen.
quelle
Basierend auf der oben vorgeschlagenen sehr eleganten Callback-Pipe-Lösung ist es möglich, sie etwas weiter zu verallgemeinern, indem zusätzliche Filterparameter weitergegeben werden. Wir haben dann:
callback.pipe.ts
Komponente
html
quelle
Hier ist ein Beispiel, das ich vor einiger Zeit erstellt und über das ich gebloggt habe und das einen funktionierenden Plunk enthält. Es bietet eine Filterpipe, mit der jede Liste von Objekten gefiltert werden kann. Sie geben im Grunde nur die Eigenschaft und den Wert {key: value} in Ihrer ngFor-Spezifikation an.
Es unterscheidet sich nicht wesentlich von der Antwort von @ NateMay, außer dass ich es relativ ausführlich erkläre.
In meinem Fall habe ich eine ungeordnete Liste nach Text (filterText) gefiltert, den der Benutzer mit dieser Art von Markup gegen die Eigenschaft "label" der Objekte in meinem Array eingegeben hat:
https://long2know.com/2016/11/angular2-filter-pipes/
quelle
Der erste Schritt, den Sie mit Filter
@Pipe
in Ihrer Datei component.ts erstellen:your.component.ts
Und Datenstruktur des Personenobjekts:
person.ts
Aus Ihrer Sicht in einer HTML-Datei:
your.component.html
quelle
Dies ist Ihr Array
Dies ist Ihre ngFor-Schleife. Filtern nach:
Dort verwende ich filterProduct Instant of Products, weil ich meine Originaldaten beibehalten möchte. Hier wird das Modell _filterText als Eingabefeld verwendet. Wann immer es eine Änderung gibt, wird die Setter-Funktion aufgerufen. In setFilterText wird performProduct aufgerufen, und es wird nur das Ergebnis zurückgegeben, das mit der Eingabe übereinstimmt. Ich verwende Kleinbuchstaben für Groß- und Kleinschreibung.
quelle
Nach einigem googeln bin ich rübergekommen
ng2-search-filter
. In nimmt Ihr Objekt und wendet den Suchbegriff auf alle Objekteigenschaften an, die nach einer Übereinstimmung suchen.quelle
Ich habe etwas gefunden, um einen Filter zu erstellen, der ein Objekt passiert, dann kann ich ihn wie einen Mehrfachfilter verwenden:
Ich habe diese Beauty-Lösung gemacht:
filter.pipe.ts
component.ts
component.html
quelle