2012-07-30 15 views
119

Ich verwende eine ng-Repeat-Richtlinie mit Filter wie folgt:AngularJS - wie ein ngRepeat gefilterte Ergebnis Verweis erhalten

ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4" 

und ich kann die erbrachten Ergebnisse sehen in Ordnung; Jetzt möchte ich ein wenig Logik für dieses Ergebnis in meinem Controller ausführen. Die Frage ist, wie kann ich die Ergebnis-Artikel-Referenz greifen?

Update:


Nur um zu klären: Ich versuche, ein Auto komplett zu erstellen, habe ich diesen Eingang:

<input id="queryInput" ng-model="query" type="text" size="30" placeholder="Enter query"> 

und dann die gefilterten Ergebnisse:

<ul> 
    <li ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4">{{item.name}}</li> 
</ul> 

jetzt möchte ich das Ergebnis navigieren und eines der Elemente auswählen .

Antwort

245

UPDATE: Hier ist ein einfacher Weg als das, was vorher war.

<input ng-model="query"> 
<div ng-repeat="item in (filteredItems = (items | orderBy:'order_prop' | filter:query | limitTo:4))"> 
    {{item}} 
</div> 

Dann ist $scope.filteredItems zugänglich.

+0

Danke für die Antwort, bitte meine Update sehen. Wie würden Sie dies implementieren, beachten Sie, dass ich die gesamte Liste der Elemente auf init –

+0

Ok, aktualisiert es. –

+0

super cool, danke dafür. Ich wünschte, es wäre ein eingebautes Feature von NG –

29

Hier ist die Filterversion von Andy Joslins Lösung.

Aktualisierung: BREAKING CHANGE. Ab Version 1.3.0-beta.19 (this commit) haben Filter keinen Kontext und this wird an den globalen Gültigkeitsbereich gebunden. Sie können den Kontext entweder als Argument übergeben oder die neue Alias-Syntax in ngRepeat, 1.3.0-beta.17 + verwenden.

// pre 1.3.0-beta.19 
yourModule.filter("as", function($parse) { 
    return function(value, path) { 
    return $parse(path).assign(this, value); 
    }; 
}); 

// 1.3.0-beta.19+ 
yourModule.filter("as", function($parse) { 
    return function(value, context, path) { 
    return $parse(path).assign(context, value); 
    }; 
}); 

Dann Ihrer Ansicht nach

<!-- pre 1.3.0-beta.19 --> 
<input ng-model="query"> 
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 | as:'filteredItems'"> 
{{item}} 
</div> 

<!-- 1.3.0-beta.19+ --> 
<input ng-model="query"> 
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 | as:this:'filteredItems'"> 
{{item}} 
</div> 

<!-- 1.3.0-beta.17+ ngRepeat aliasing --> 
<input ng-model="query"> 
<div ng-repeat="item in items | orderBy:'order_prop' | filter:query | limitTo:4 as filteredItems"> 
{{item}} 
</div> 

, die Sie $scope.filteredItems Zugang gibt.

+0

Danke! Können Sie erklären, wie der Filtercode funktioniert?Ich bin nicht vertraut mit $ Parse, und die eckigen Dokumente haben mir nicht geholfen, zu dekodieren, wie Ihr Filter genau funktioniert. – Magne

+2

@Magne Kein Problem! Bitte sehen Sie sich das Update an, da es Ihnen vielleicht einige Schmerzen ersparen wird. Um Ihre Frage zu beantworten, ist "$ parse" Angulars [Ausdruck-Compiler] (https://docs.angularjs.org/api/ng/service/$parse) .. Zum Beispiel wird es die Zeichenfolge 'nehmen some.object.property 'und gibt eine Funktion zurück, mit der Sie entweder den angegebenen Pfad für einen angegebenen Kontext festlegen oder abrufen können. Ich benutze es hier, um Filterergebnisse speziell für das $ scope festzulegen. Ich hoffe, das beantwortet deine Frage. – kevinjamesus86

10

Ich kam mit einer etwas besseren Version von Andys Lösung. In seiner Lösung beobachtet ng-repeat den Ausdruck, der die Zuweisung enthält. Jede Digest-Schleife wertet diesen Ausdruck aus und weist das Ergebnis der Bereichsvariablen zu.

Das Problem mit dieser Lösung besteht darin, dass Sie möglicherweise Probleme mit Zuweisungen haben, wenn Sie sich in einem untergeordneten Bereich befinden. Dies ist der gleiche Grund, warum Sie eine dot in ng-model haben sollten.

Die andere Sache, die ich nicht an dieser Lösung gefällt ist, dass es die Definition des gefilterten Array irgendwo in der Ansicht Markup vergräbt. Wenn es an mehreren Stellen in Ihrer Ansicht oder auf Ihrem Controller verwendet wird, kann es zu Verwirrung führen.

Eine einfachere Lösung ist, sich nur auf eine Funktion, eine Uhr in Ihrem Controller zu platzieren, die die Zuordnung macht:

$scope.$watch(function() { 
    $scope.filteredItems = $scope.$eval("items | orderBy:'order_prop' | filter:query | limitTo:4"); 
}); 

Diese Funktion wird bei jedem verdauen Zyklus ausgewertet werden, um die Leistung mit Andys Lösung vergleichbar sein sollte. Sie können in der Funktion auch eine beliebige Anzahl von Zuweisungen hinzufügen, um sie alle an einem Ort zu speichern, anstatt sie über die Ansicht zu verteilen.

In der Ansicht, würden Sie die gefilterte Liste verwenden Sie einfach direkt:

<ul> 
    <li ng-repeat="item in filteredItems">{{item.name}}</li> 
</ul> 

Here's a fiddle where this is shown in a more complicated scenario.

+0

Super sauber und verschmutzt nicht die Struktur, schön! – kuzyn

+0

diese lösung ist perfekt für mich..ich benutzte ion sammlung wiederholen statt ng wiederholen..das, warum die angenommene antwort funktionierte nicht für mich – Lakshay

+0

Vielen Dank ...... dies rettete mich nur. –

21

so etwas wie dies versucht, das Problem mit der ng-Wiederholung ist, dass es wegen dieses Kind Umfang schafft Sie können nicht

filteritems Zugang

von der Steuerung

<li ng-repeat="doc in $parent.filteritems = (docs | filter:searchitems)" ></li> 
14

Update:

Auch nach 1.3.0. Wenn Sie es auf den Bereich des Controllers oder der Eltern setzen möchten, können Sie das nicht mit als Syntax tun. Zum Beispiel, wenn ich den folgenden Code haben:

<div>{{labelResults}}</div> 
<li ng-repeat="label in (labels | filter:query | as labelResults)"> 
</div> 

die oben wird nicht Arbeit. Der Weg darum herum zu gehen, wird mit den Eltern $ wie so:

<li ng-repeat="label in ($parent.labelResults = (labels | filter:query))"> 
+0

Es ist gut zu beachten, dass wenn Sie ein Limit haben, um dies zu filtern. Es wird nicht in der $ parent.labelResults – Zack

+0

widerspiegeln Wenn ich 'console.log labelResults' Ich bekomme immer die Daten einen Filter später. Es ist nicht das Ergebnis des gerade geänderten Filters, sondern derjenige der vorherigen Änderung. Hattest du dieses Problem nicht? – Anna