web-dev-qa-db-ja.com

Angular ng-repeatのテキストとしてのorderBy番号のソート

私はこのデータを持っています:

[{"id":"42","firstname":"Sarah","lastname":"Dilby","age":"40","cars":"Yaris"},
{"firstname":"Jason","lastname":"Diry","age":"5","id":"5"},
{"id":"6","firstname":"Bilson","lastname":"Berby","age":"1","cars":"Tipo"}]

Idまたはng-repeatの年齢でorderByすると、数値がテキストとしてソートされます。これがどこかに問題があると書かれているのを見つけることができないので、コードに問題があると推測しています。私はこのフィドルを作成しました: http://jsfiddle.net/vsbGH/1/ テンプレートについては申し訳ありませんが、jsfiddleはhtmlで許可していませんボックス。とにかく、これはデータをロードしてソートするコードです:

//user data
app.service('People', function() {
var People = {};
People.details = [{"id":"42","firstname":"Sarah","lastname":"Dilby","age":"40","cars":"Yaris"},
                  {"firstname":"Jason","lastname":"Diry","age":"5","id":"5"},
                  {"id":"6","firstname":"Bilson","lastname":"Berby","age":"1","cars":"Tipo"}]
return People;
});

//list ctrl
controllers.listCtrl = function ($scope,People) {
 $scope.people = People.details;

 $scope.sortList = function(sortname) {
    $scope.sorter = sortname;
 }
}

そして、これはテンプレートのng-repeat部分です:

<tr ng-repeat="person in people | orderBy:sorter ">
        <td>{{person.id | number}}</td>
        <td>{{person.firstname}} </td>
        <td>{{person.lastname}} </td>
        <td>{{person.age | number}}</td>
        <td>{{person.cars}} </td>
 </tr>

数値データが数値としてソートされていない理由と、テキストとしてソートされている理由を理解していただけるとありがたいです。

32
dewd

最も適切な解決策は、JSONオブジェクトにある数字を正しくフォーマットすること、つまり引用符で囲まないことだと思います。そう:

 [{"id":"42","firstname":"Sarah","lastname":"Dilby","age":"40","cars":"Yaris"},
  {"firstname":"Jason","lastname":"Diry","age":"5","id":"5"},
  {"id":"6","firstname":"Bilson","lastname":"Berby","age":"1","cars":"Tipo"}]

になる:

[{"id":42,"firstname":"Sarah","lastname":"Dilby","age":40,"cars":"Yaris"},
 {"firstname":"Jason","lastname":"Diry","age":5,"id":5},
 {"id":6,"firstname":"Bilson","lastname":"Berby","age":1,"cars":"Tipo"}]

JSONデータの形式を修正できない場合、SergLのソリューションは良いと思います。

これに追加するには、特定のケースでの問題は、サーバー側でPHPのjson_encode関数を使用することです。デフォルトでは、数字を文字列として扱います。修正するには、PHP=)スクリプトのJSON_NUMERIC_CHECKオプションをエンコードメソッドに追加する必要がありました。

json_encode($assoc_array,JSON_NUMERIC_CHECK);
50
dewd

JSONを変更する必要はありません。次のような関数をorderByフィルターに渡すことができます。

$scope.sorterFunc = function(person){
    return parseInt(person.id);
};

<tr ng-repeat="person in people | orderBy:sorterFunc ">
        <td>{{person.id | number}}</td>
        <td>{{person.firstname}} </td>
        <td>{{person.lastname}} </td>
        <td>{{person.age | number}}</td>
        <td>{{person.cars}} </td>
 </tr>
28
Ragnar

Ng-repeatディレクティブ内では、数値フィルターを使用しています

<td>{{person.id | number}}</td>

フィルターは出力のフォーマットに使用されますが、モデルのプロパティは更新されません。たとえば、person.id = 1234.56789は1,234.568としてレンダリングされます。

上記のように、年齢をタイプ番号に変換する必要があります。次に、orderByは正常に機能します。たとえば、サービス内で:

angular.forEach(People.details, function (detail) {
  detail.age = parseFloat(detail.age);
});
15
SergeL

orderBy値が別の文字列を指す変数ではない場合ではなく、並べ替えに使用する属性の場合は、引用符で囲む必要があります。

person in people | orderBy:'-id'

Intまたはfloatを解析しても、まだ正しくソートされていない場合、これが原因である可能性があります。 <:/(それは私の劣等生のキャップです)

5
Ktel

テキストフィールドとngModelを使用して、注文したモデルの値を変更するときに、同じ問題に直面しました。値が文字列と見なされたため。

新しいHTML5で <input type="number" /> 、Angularは、入力フィールドの値を数値(フロートだと思います)に解析します。これは正しい順序を取得するのに役立ちました。

3
naitsirch

orderByがスコープまたはその分離されていない祖先によって所有されているメソッドを指し、このメソッドが文字列からキャストされた数値を返すようにします。このメソッドを追加するには、ngRepeatインスタンスによって作成されたpersonスコープを継承するディレクティブを記述する必要があります。

さらに、あなたの場合、年齢は整数である可能性のある文字列であるため、数値ソートはネイティブに適用されます。

データサーバー側を変更できない場合は、フェッチ中にクライアント側で変更します。

0
lib3d