0

キーと値のペアの配列を、特定のプロパティの最初の文字で値をグループ化するオブジェクトに分割するカスタム フィルターを作成しました。例えば

入力:[{foo: 'bar'}, {faz: 'baz'}, {boo: 'foo'}]

出力:{f: [{foo: bar}, {faz: baz}], b: [{boo, foo}]}

ただし、このフィルターは Angular で無限消化エラーを引き起こしているようです。

var app = angular.module('app', []);

app.controller('ctrl', ['$scope', function($scope){
  $scope.arr = [{name: 'foo', def: 'bar'}, {name: 'faz', def: 'baz'}, {name: 'boo', def: 'foo'}]
}]);

app.filter('firstLetterChunks', function() {
    return function(input){
        var chunks={};
        for(var i = 0; i < input.length; i++){
            var firstLetter = input[i].name[0].toUpperCase();
            if(!(chunks.hasOwnProperty(firstLetter))) {
                chunks[firstLetter]=[];
            }
            chunks[firstLetter].push(input[i]);
        }

        return chunks;
    };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app">
  <div ng-controller="ctrl">
    This caused a infdig error. Check your console.
    <div ng-repeat="(firstletter, values) in arr | firstLetterChunks">
      {{firstletter}}
      <hr>
      <div ng-repeat="value in values">
        {{value}}
      </div>
    </div>
  </div>
</div>

そして、私はその理由を理解できません。私が見つけたものから、これは通常、フィルターでモデルを変更して ng-repeat を再トリガーすることによって引き起こされますが、私はこれを行っているとは思いません。

4

1 に答える 1

0

これは、すべてのフィルター呼び出しが基本的に新しい ID を持つ新しいオブジェクトを返すため、Angular は何かが変更されたと見なすために発生します。これにより、新しいダイジェスト サイクルがトリガーされ、これが 10 個のダイジェストの制限に達するまで続きます。

キャッシュを使用して計算されたオブジェクトを保存し、フィルターを保持することでそれを修正する他の方法があると思いますが、コードを次のように変更しましたが、これはまったく同じように機能しますがchunks、配列が変更された場合は再計算する必要があります。

var app = angular.module('app', []);

app.controller('ctrl', ['$scope', function($scope){

  $scope.arr = [{name: 'foo', def: 'bar'}, {name: 'faz', def: 'baz'}, {name: 'boo', def: 'foo'}];

    function getChunks() {
        var input = $scope.arr;
        var chunks = {};
        for(var i = 0; i < input.length; i++){
            var firstLetter = input[i].name[0].toUpperCase();
            if(!(chunks.hasOwnProperty(firstLetter))) {
                chunks[firstLetter]=[];
            }
            chunks[firstLetter].push(input[i]);
        }

        return chunks;
    }

    $scope.chunks = getChunks();
}]);

HTML 呼び出しを次のように変更します。

<div ng-repeat="(firstletter, values) in chunks">

フィドル

于 2015-03-13T22:28:36.787 に答える