11

ControllerFilter: notarray Erwartete Array aber erhalten: 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(); 
    } 

Angular Anruf

$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(); 
     } 
    }; 
    }) 

Ich bin nicht sicher, warum Sie den Filter mit bekomme ich die Ausnahme.

sah auch in eckigen doc https://docs.angularjs.org/error/filter/notarray Mein Ergebnis ist Array, aber nicht sicher, warum ich solche Ausnahme bekomme.

Beispiel Ergebnis aus Backend ich bekomme.

[{"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> 

Antwort

53

Das Problem, weil Sie track by $index verwenden auftritt, bevor Sie Ihren Filter anwenden. Um dies zu beheben, ändern Sie Ihren Ausdruck zu:

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

Der track by Ausdruck sollte immer in der letzten sein, nachdem alle Filter. Es ist eine Regel in der Dokumentation erwähnt: ngRepeat

Erläuterung:

Wenn Sie nicht track by $index in ngRepeat verwenden Sie die Eingabe für alle verwendeten Filter ist das Array, das heißt, wenn seine

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

dann ist items der Eingang, der standardmäßig an die Filter übergeben wird, und die Filterung erfolgt an diesem Eingang.

Wenn Sie jedoch track by $index verwenden, die Eingabe in den Filter $index anstelle von items und daher wird der Fehler: zuerst die Filter alle

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

Daher Um dem entgegenzuwirken, wobei die Anordnung durchlaufen und die Das gefilterte Ergebnis wird mit track by $index verwendet.

Hoffe das klärt es auf.

+0

könnten Sie bitte die Logik hinter Ihrem Vorschlag –

+3

Es ist eine Regel erwähnt in der Dokumentation beschreiben. Filter sollten vor der Spur durch Ausdruck angewendet werden. Siehe in Dokumenten: https: //docs.angularjs.org/api/ng/directive/ngRepeat –

+0

Nachdem ich 2 Stunden damit verbracht hatte, herauszufinden, warum der Filter auf der Angular-Website funktionierte und meiner nicht, war dies die einzige Antwort, die mein Problem löste! Unnötig zu sagen, dass ich wahrscheinlich die Dokumente öffnen und erneut lesen müsste. Aber das ist sehr unintuitiv und der Fehler hilft überhaupt nicht, warum 'track by $ index' immer der letzte Ausdruck sein sollte? Macht keinen Sinn in meinem Kopf. – MacK

2

Sie sollten immer track by am Ende des Ausdrucks verwenden

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

Da während für Spur einen Ausdruck für ng-repeat Winkel Bedürfnisse Bewertung des Endergebnisses durch an die Arbeit. Wenn Sie es am Ende angeben, wird Ihr Filter angewendet und track by wird bei der endgültigen Ausgabe berechnet. Sie können den Quellcode bei eckigen Dokumenten sehen.

Gemäß der Dokumentation von 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.