2012-07-30 20 views
119

Sto usando una direttiva ng-repeat con filtro in questo modo:AngularJS - come ottenere un riferimento risultato ngRepeat filtrata

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

e posso vedere i risultati resi bene; ora voglio fare un po 'di logica su quel risultato nel mio controller. La domanda è: come posso prendere il riferimento agli articoli dei risultati?

Aggiornamento:


Giusto per chiarire: Sto cercando di creare un auto completo, ho questo ingresso:

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

e poi i risultati filtrati:

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

ora voglio navigare il risultato e selezionare uno degli elementi .

risposta

245

UPDATE: ecco un modo più semplice di quello che c'era prima.

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

Quindi $scope.filteredItems è accessibile.

+0

Grazie per la risposta, si prega di vedere il mio aggiornamento. Come vorresti implementarlo, tieni presente che ottengo l'intero elenco di elementi su init –

+0

Ok, l'ho aggiornato. –

+0

super cool, grazie per quello. Vorrei che fosse una funzionalità integrata di NG –

29

Ecco la versione del filtro della soluzione di Andy Joslin.

Aggiornamento: CAMBIAMENTO DI ROTTURA. A partire dalla versione 1.3.0-beta.19 (this commit) i filtri non hanno un contesto e this sarà associato all'ambito globale. È possibile passare il contesto come argomento o utilizzare la nuova sintassi di aliasing in ngRepeat, 1.3.0-beta.17 +.

// 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); 
    }; 
}); 

Quindi secondo lei

<!-- 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> 

che consente di accedere a $scope.filteredItems.

+0

Grazie! Potresti spiegare come funziona il codice del filtro?Non ho familiarità con $ parse, e i documenti angolari non mi hanno aiutato a decifrare come funziona esattamente il filtro. – Magne

+2

@Magne Nessun problema! Si prega di controllare l'aggiornamento anche se potrebbe salvarvi un po 'di dolore e sofferenza lungo la strada. Per rispondere alla tua domanda, in breve, '$ parse' è Angular's [espressione compilatore] (https://docs.angularjs.org/api/ng/service/$parse) .. Ad esempio, prenderà la stringa ' some.object.property 'e restituisce una funzione che consente di impostare o ottenere un valore su detto percorso per un contesto specificato. Lo sto usando per impostare i risultati del filtro su $ scope qui, in particolare. Spero che questo risponda alla tua domanda. – kevinjamesus86

10

Mi è venuta in mente una versione leggermente migliore della soluzione di Andy. Nella sua soluzione ng-repeat pone un orologio sull'espressione che contiene il compito. Ogni ciclo di digest valuterà quell'espressione e assegnerà il risultato alla variabile scope.

Il problema con questa soluzione è che si potrebbero incorrere in problemi di assegnazione se si è in un ambito figlio. Questa è la stessa ragione per cui dovresti avere un dot in ng-model.

L'altra cosa che non mi piace di questa soluzione è che nasconde la definizione dell'array filtrato da qualche parte nel markup della vista. Se viene utilizzato in più punti nella visualizzazione o nel controller, può generare confusione.

Una soluzione più semplice è quella di appena posto un orologio nel controllore su una funzione che rende l'assegnazione:

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

Questa funzione sarà valutata durante ogni ciclo di digerire quindi le prestazioni dovrebbero essere paragonabili con la soluzione di Andy. È inoltre possibile aggiungere qualsiasi numero di compiti nella funzione per mantenerli tutti in un unico posto piuttosto che sparsi nella vista.

Nella vista, si sarebbe solo utilizzare l'elenco filtrato direttamente:

<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 pulito e non inquina la struttura, bello! – kuzyn

+0

questa soluzione è perfetta per me..si stavo usando la raccolta di ionic repeat invece di ng repeat..questo perché la risposta accettata non ha funzionato per me – Lakshay

+0

Grazie mille ...... questo mi ha appena salvato. –

21

provare qualcosa di simile, il problema con il ng-repeat è che crea ambito bambino a causa di quel non è possibile accedere

filteritems

dal controller

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

Aggiornamento:

Anche dopo 1.3.0. se vuoi metterlo sullo scope del controller o del genitore non puoi farlo con la sintassi come. Per esempio se ho il seguente codice:

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

quanto sopra sarà non lavoro. Il modo di andare in giro sta usando il $ genitore come così:

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

È bene notare che se si dispone di un filtro limitTo su questo. Non si rifletterà nel $ parent.labelResults – Zack

+0

Se io 'console.log labelResults' ottengo sempre il filtro dei dati in un secondo momento. Non è il risultato del filtro appena cambiato, ma quello del cambiamento precedente. Non hai avuto questo problema? – Anna

Problemi correlati