11

regolatoreFiltro: array notarray previsto, ma ha ricevuto: 0

@RequestMapping(value = "/graphs", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) 
    public Collection<Graph> getSkeletonGraph() 
    { 
     log.debug("REST request to get current graphs"); 
     return graphService.getSkeletonGraphs(); 
    } 

chiamata angolare

$scope.graphs = []; 
    Graph.getGraphs().$promise.then(function(result) 
    { 
     $scope.graphs = result; 
    }); 



    angular.module('sampleApplicationApp').factory('Graph', function($resource) 
    { 
     return { 
     getGraphs: function() { 
      return $resource('api/graphs/:id').query(); 
     } 
    }; 
    }) 

io non sono sicuro perché utilizzando il filtro ottengo l'eccezione.

guardato anche in angular doc https://docs.angularjs.org/error/filter/notarray Il mio risultato è array ma non sono sicuro del motivo per cui sto ottenendo tale eccezione.

Risultato del campione dal backend che sto ottenendo.

[{"id":"135520b0-9e4b-11e5-a67e-5668957d0149","area":"Bingo","models":[],"enumerateds":[]},{"id":"0db925e0-9e53-11e5-a67e-5668957d0149","area":"jin","models":[],"enumerateds":[]},{"id":"7a717330-9788-11e5-b259-5668957d0149","area":"Product","models":[],"enumerateds":[]},{"id":"402d4c30-980f-11e5-a2a3-5668957d0149","area":"fgfgfg","models":[],"enumerateds":[]},{"id":"404b77b0-9e53-11e5-a67e-5668957d0149","area":"olah","models":[],"enumerateds":[]},{"id":"cd071b10-9e52-11e5-a67e-5668957d0149","area":"lolo","models":[],"enumerateds":[]},{"id":"d9808e60-9710-11e5-b112-5668957d0149","area":"catalog","models":[],"enumerateds":[]},{"id":"2aaca9f0-97e2-11e5-91cd-5668957d0149","area":"btg","models":[],"enumerateds":[]},{"id":"955e9ed0-978c-11e5-93fd-5668957d0149","area":"promotions","models":[],"enumerateds":[]},{"id":"1e441d60-980f-11e5-a2a3-5668957d0149","area":"hjuhh","models":[],"enumerateds":[]},{"id":"fb96dfe0-978d-11e5-93fd-5668957d0149","area":"voucher","models":[],"enumerateds":[]}] 

html

<li ng-repeat="g in graphs track by $index | filter:searchText"></li> 

risposta

53

Il problema si verifica perché si utilizza track by $index prima si sta applicando il filtro. Per risolvere questo, cambiare la vostra espressione:

<li ng-repeat="g in graphs | filter:searchText track by $index"></li> 

Il track by espressione dovrebbe essere sempre l'ultimo, dopo tutti i filtri. La sua regola menzionato nella documentazione: ngRepeat

Spiegazione:

Quando non si utilizza track by $index nel ngRepeat, l'ingresso per tutti i filtri utilizzati è la matrice, che è, se

ng-repeat="item in items | filter1 | filter2", 

quindi items è l'input passato ai filtri per impostazione predefinita e il filtraggio viene eseguito su questo input.

Tuttavia, quando si utilizza track by $index, l'ingresso ai filtri diventa $index anziché items e quindi l'errore:

Expected array(read: items) but received 0(read: $index).

Pertanto, per contrastare questo, la matrice viene prima passato attraverso tutti i filtri e la il risultato filtrato viene utilizzato con track by $index.

Spero che questo chiarisca tutto.

+0

potreste descrivere la logica dietro suo suggerimento –

+3

sua una regola menzionati nella documentazione. I filtri devono essere applicati prima della traccia per espressione. Vedi in documenti: https: //docs.angularjs.org/api/ng/direttiva/ngRepeat –

+0

Dopo aver passato 2 ore a cercare di capire perché il filtro sul sito Web di Angular funzionava e la mia non era questa era l'unica risposta che ha risolto il mio problema! Inutile dire che probabilmente avrei bisogno di aprire e rileggere i documenti. Tuttavia questo è molto anti-intuitivo e l'errore non aiuta affatto, perché "track by $ index" dovrebbe essere sempre l'ultima espressione? Non ha senso nella mia testa. – MacK

2

Si dovrebbe sempre utilizzare track by alla fine dell'espressione

<li ng-repeat="g in graphs | filter:searchText track by $index"></li> 

Poiché durante la valutazione di un'espressione per ng-repeat esigenze angolari il risultato finale per traccia di lavoro. Se lo fornite alla fine, il filtro verrà applicato e track by viene calcolato sull'output finale. Puoi vedere il codice sorgente su documenti angolari.

Secondo la documentazione di ng-repeat

If you are working with objects that have an identifier property, you should track by the identifier instead of the whole object. Should you reload your data later, ngRepeat will not have to rebuild the DOM elements for items it has already rendered, even if the JavaScript objects in the collection have been substituted for new ones. For large collections, this signifincantly improves rendering performance. If you don't have a unique identifier, track by $index can also provide a performance boost.

Problemi correlati