2016-07-01 9 views
4

Ich versuche, einen benutzerdefinierten Komparator für die eckige Anweisung orderBy zu implementieren. Wie Sie im Code-Schnipsel sehen können, ist der Brauch Komparator (nichts von console.log angemeldet) ignoriert, obwohl es nach dem Warum funktioniert der eckige Auftrag nicht nach dem benutzerdefinierten Vergleicher?

habe ich das Beispiel getestet funktionieren sollte angular documentation for orderBy

angular.module('orderByExample', []) 
 
.controller('ExampleController', ['$scope', function($scope) { 
 
    $scope.files = [ 
 
    {name: 'File1', size: '1.2 Mb'}, 
 
    {name: 'File2', size: '2.4 Kb'}, 
 
    {name: 'File3', size: '241 Bytes'}, 
 
    {name: 'File4', size: '2.0 Mb'}, 
 
    {name: 'File5', size: '16.1 Kb'} 
 
    ]; 
 

 
    $scope.fileSizeComparator = function(s1, s2) { 
 
    // split the size string in nummeric and alphabetic parts 
 
    console.log(s1); 
 
    console.log(s2); 
 
    var s1Splitted = s1.size.split(" "); 
 
    var s2Splitted = s2.size.split(" "); 
 
    if (s1Splitted[1] === s2Splitted[1]) { 
 
     // if size type is the same, compare the number 
 
     return s1Splitted[0] > s2Splitted[0]; 
 
    } 
 
    // default : compare on size type Mb > Kb > Bytes 
 
    return s1Splitted[1] > s2Splitted[1]; 
 
    }; 
 
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 
<div ng-app="orderByExample"> 
 
    <div ng-controller="ExampleController"> 
 
    <table> 
 
     <tr> 
 
     <th>Name</th> 
 
     <th>Size</th> 
 
     </tr> 
 
     <tr ng-repeat="file in files | orderBy:'size':false:fileSizeComparator"> 
 
     <td>{{file.name}}</td> 
 
     <td>{{file.size}}</td> 
 
     </tr> 
 
    </table> 
 
    </div> 
 
</div>
Code aus der eckigen Dokumentation auf JsFiddle und es funktioniert auch nicht. Irgendwelche Ideen?

+1

im letzten Beispiel der Winkel Dokumentation suchen, sagt es der dritte Parameter sein sollte lesen Sie als Funktion –

Antwort

10

Ich fand die Lösung nach einiger Hilfe von @morels: ja ich sollte tatsächlich 1 und -1 zurückgeben. Das Hauptproblem war jedoch, dass der Vergleicher ignoriert wurde. Offensichtlich liegt es daran, dass diese Funktion nur für den Winkel 1,5,7 und höher verfügbar ist. Ich musste auch die .split über die .value der übergebenen Parameter von s1 und s2 verwenden.

Hier ist die Arbeitslösung im Code-Schnipsel:

angular.module('orderByExample', []) 
 
.controller('ExampleController', ['$scope', function($scope) { 
 
    $scope.files = [ 
 
    {name: 'File1', size: '1.2 Mb'}, 
 
    {name: 'File2', size: '2.4 Kb'}, 
 
    {name: 'File3', size: '241 Bytes'}, 
 
    {name: 'File4', size: '2.0 Mb'}, 
 
    {name: 'File5', size: '16.1 Kb'} 
 
    ]; 
 

 
    $scope.fileSizeComparator = function(s1, s2) { 
 
    // split the size string in nummeric and alphabetic parts 
 
    var s1Splitted = s1.value.split(" "); 
 
    var s2Splitted = s2.value.split(" "); 
 
    if (s1Splitted[1] === s2Splitted[1]) { 
 
     // if size type is the same, compare the number 
 
     return parseFloat(s1Splitted[0]) > parseFloat(s2Splitted[0]) ? -1 : 1; 
 
    } 
 
    // default : compare on size type Mb > Kb > Bytes 
 
    return s1Splitted[1] > s2Splitted[1] ? -1 : 1; 
 
    }; 
 
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script> 
 
<div ng-app="orderByExample"> 
 
    <div ng-controller="ExampleController"> 
 
    <table> 
 
     <tr> 
 
     <th>Name</th> 
 
     <th>Size</th> 
 
     </tr> 
 
     <tr ng-repeat="file in files | orderBy:'size':false:fileSizeComparator"> 
 
     <td>{{file.name}}</td> 
 
     <td>{{file.size}}</td> 
 
     </tr> 
 
    </table> 
 
    </div> 
 
</div>

1

Da sollten Sie -1,0,1 nicht true,false zurückgeben.

die official documentation Sie können das Format eines typischen Vergleichsfunktion siehe folgende:

$scope.localeSensitiveComparator = function(v1, v2) { 
// If we don't get strings, just compare by index 
if (v1.type !== 'string' || v2.type !== 'string') { 
    return (v1.index < v2.index) ? -1 : 1; 
} 

// Compare strings alphabetically, taking locale into account 
return v1.value.localeCompare(v2.value); }; 

Bitte umschreiben als:

$scope.fileSizeComparator = function(s1, s2) { 
    // split the size string in nummeric and alphabetic parts 
    console.log(s1); 
    console.log(s2); 
    var s1Splitted = s1.size.split(" "); 
    var s2Splitted = s2.size.split(" "); 
    if (s1Splitted[1] === s2Splitted[1]) { 
     // if size type is the same, compare the number 
     if (s1Splitted[0] > s2Splitted[0]) 
     return 1; 
     else 
     return -1; 
    } 
    // default : compare on size type Mb > Kb > Bytes 
    return s1Splitted[1] > s2Splitted[1] ? -1 : 1; 
    }; 

Beachten Sie, dass Sie nie Gleichheit dh 0 verpassen .

+0

Ich habe herausgefunden, dass das Hauptproblem die eckige Version war. Anscheinend benötigt der benutzerdefinierte Komparator Winkel 1.5.7 um zu arbeiten. Danke für die Hilfe, ich sollte tatsächlich 1 oder -1 anstatt wahr oder falsch zurückgeben. –

-2

gefällt das

ng-repeat="file in files | orderBy: sizeFilter: true" 

$scope.sizeFilter=function(file){ 
     $scope.size = file.size; 
     return $scope.size; 
}; 
+1

Dies führt eine neue Bereichsvariable "Größe" ohne erklärlichen Grund ein. Verpasst auch vollständig die Absicht des OP, den Byte-, Kb-, Mb-Teil der Zeichenkette zu verwenden. – Gary