1. ホーム
  2. angularjs

[解決済み] ng-repeatでのカスタムソート機能

2022-09-12 14:09:42

質問

ユーザーが選択したオプションに応じて特定の番号を表示するタイルのセットを持っています。 私は今、表示されるどの番号でもソートを実装したいと思います。

以下のコードは、私がそれを実装した方法を示しています(親カードのスコープで値を取得/設定することによって)。 さて、orderBy関数は文字列を受け取るので、cardスコープにcurOptionValueという変数をセットして、それでソートしようとしましたが、うまくいかないようです。

そこで、問題は、どのようにカスタムのソート関数を作成するかということになります。

<div ng-controller="aggViewport" >
<div class="btn-group" >
    <button ng-click="setOption(opt.name)" ng-repeat="opt in optList" class="btn active">{{opt.name}}</button>
</div>
<div id="container" iso-grid width="500px" height="500px">
    <div ng-repeat="card in cards" class="item {{card.class}}" ng-controller="aggCardController">
        <table width="100%">
            <tr>
                <td align="center">
                    <h4>{{card.name}}</h4>
                </td>
            </tr>
            <tr>
                <td align="center"><h2>{{getOption()}}</h2></td>
            </tr>
        </table>        
    </div>
</div>

とコントローラ.

module.controller('aggViewport',['$scope','$location',function($scope,$location) {
    $scope.cards = [
        {name: card1, values: {opt1: 9, opt2: 10}},
        {name: card1, values: {opt1: 9, opt2: 10}}
    ];

    $scope.option = "opt1";

    $scope.setOption = function(val){
        $scope.option = val;
    }

}]);

module.controller('aggCardController',['$scope',function($scope){
    $scope.getOption = function(){
        return $scope.card.values[$scope.option];
    }
}]);

どのように解決するのですか?

実は orderBy フィルタは文字列だけでなく関数も引数に取ることができます。例えば orderBy のドキュメントを参照してください。 https://docs.angularjs.org/api/ng/filter/orderBy ):

関数です。ゲッター関数です。この関数の結果は、ソートされます 演算子でソートされます。

つまり、独自の関数を書くことができるわけです。例えば、opt1とopt2の合計でカードを比較したい場合(これは作り話ですが、要は任意の関数を持つことができます)、コントローラに書くことになります。

$scope.myValueFunction = function(card) {
   return card.values.opt1 + card.values.opt2;
};

と入力し、テンプレートで

ng-repeat="card in cards | orderBy:myValueFunction"

以下は動作中のjsFiddleです。

もう一つ注目すべきは orderBy の一例であることです。 AngularJSのフィルター の一例ですので、非常に特殊な順序付けが必要な場合は、独自のフィルタを書くことができます(ただし orderBy で十分だと思います)。