12

ng-repeat の angular.js 条件付きマークアップに従って、グループ化を行うカスタム フィルターを作成しようとしました。オブジェクトのアイデンティティと変更を監視しているモデルに関して問題が発生しましたが、コンソールにエラーが表示されなくなったため、最終的にはうまくいったと思いました.

私が間違っていたことが判明しました.

<div ng-repeat="r in blueprints | orderBy:sortPty | startFrom:currentPage*pageSize | limitTo:pageSize | group:3">
      <div ng-repeat="b in r">

「$digest() の反復が 10 回に達しました。中止します!」という恐ろしいメッセージが表示されます。再びエラーメッセージ。

これが私のグループフィルターです:

filter('group', function() {
  return function(input, size) {
    if (input.grouped === true) {
      return input;
    }
  var result=[];
  var temp = [];
  for (var i = 0 ; i < input.length ; i++) {
      temp.push(input[i]);
      if (i % size === 2) {
          result.push(temp);
          temp = [];
      }
  }
  if (temp.length > 0) {
      result.push(temp);
  }
  angular.copy(result, input);
  input.grouped = true;
  return input;
}; 
}).

angular.copy入力での使用と.groupedマーカーの両方に注意し ください

さらに、グループ化のロジックは少しナイーブだと思いますが、それは別の話です。これは私を夢中にさせているので、どんな助けも大歓迎です。

4

3 に答える 3

15

ここでの本当の問題は、新しい変数を作成してフィルターから出力するのではなく、入力を変更していることのようです。これにより、入力した変数を監視しているすべてのものに対して監視がトリガーされます。

独自のフィルターを完全に制御する必要があるため、そこに「grouped==true」チェックを追加する理由は実際にはありません。ただし、それがアプリケーションの必須事項である場合は、入力ではなく、フィルターの結果に「grouped==true」を追加する必要があります。

フィルタが機能する方法は、入力を変更して別の結果を返すことです。次のフィルタは前のフィルタの結果を処理します...したがって、「フィルタされた」チェックはitem in items | filter1 | filter2 | filter3、filter1がアイテムをフィルタリングし、filter2がfilter1の結果をフィルタリングする場合、ほとんど無関係になります。 filter3は、フィルター2の結果をフィルター処理します...それが理にかなっている場合。

これが私がたった今作ったものです。それが機能するかどうかは(まだ)わかりませんが、基本的な考え方はわかります。片側に配列を取り、反対側に配列の配列を吐き出します。

app.filter('group', function(){
   return function(items, groupSize) {
      var groups = [],
         inner;
      for(var i = 0; i < items.length; i++) {
         if(i % groupSize === 0) {
            inner = [];
            groups.push(inner);
         }
         inner.push(items[i]);
      }
      return groups;
   };
});

HTML

<ul ng-repeat="grouping in items | group:3">
    <li ng-repeat="item in grouping">{{item}}</li>
</ul>

編集

おそらく、コード内のこれらすべてのフィルターを確認する方が良いでしょうが、$ digestで常に再評価する必要があるため、問題が発生しているように見えます。だから私はあなたがこのようなことをすることを提案します:

app.controller('MyCtrl', function($scope, $filter) {
   $scope.blueprints = [ /* your data */ ];
   $scope.currentPage = 0;
   $scope.pageSize = 30;
   $scope.groupSize = 3;
   $scope.sortPty = 'stuff';

   //load our filters
   var orderBy = $filter('orderBy'),
       startFrom = $filter('startFrom'),
       limitTo = $filter('limitTo'),
       group = $filter('group'); //from the filter above

   //a method to apply the filters.
   function updateBlueprintDisplay(blueprints) {
        var result = orderBy(blueprints, $scope.sortPty);
        result = startForm(result, $scope.currentPage * $scope.pageSize);
        result = limitTo(result, $scope.pageSize);
        result = group(result, 3);
        $scope.blueprintDisplay = result;
   }

   //apply them to the initial value.
   updateBlueprintDisplay();

   //watch for changes.
   $scope.$watch('blueprints', updateBlueprintDisplay);
});

次に、マークアップで:

<ul ng-repeat="grouping in blueprintDisplay">
   <li ng-repeat="item in grouping">{{item}}</li>
</ul>

...そこにはタイプミスがあると思いますが、それが基本的な考え方です。


もう一度編集:あなたはすでにこの答えを受け入れていることを知っていますが、これを行うためのもう1つの方法があります。私は最近、あなたがもっと良いと思うかもしれないことを学びました。

<div ng-repeat="item in groupedItems = (items | group:3 | filter1 | filter2)">
    <div ng-repeat="subitem in items.subitems">
    {{subitem}}
    </div>
</div>

これにより、$scopeに$scope.groupedItemsという新しいプロパティがオンザフライで作成され、フィルタリングおよびグループ化された結果が効果的にキャッシュされます。

それを回転させて、それがあなたのためにうまくいくかどうか私に知らせてください。そうでなければ、私は他の答えがより良いかもしれないと思います。

于 2013-01-22T16:22:10.853 に答える
1

angular.filterモジュールの groupBy フィルターを使用して、次のようなことを行うことができます:
usage:(key, value) in collection | groupBy: 'property'または 'propperty.nested'
JS:

$scope.players = [
  {name: 'Gene', team: 'alpha'},
  {name: 'George', team: 'beta'},
  {name: 'Steve', team: 'gamma'},
  {name: 'Paula', team: 'beta'},
  {name: 'Scruath', team: 'gamma'}
];

HTML:

<ul ng-repeat="(key, value) in players | groupBy: 'team'" >
  Group name: {{ key }}
  <li ng-repeat="player in value">
    player: {{ player.name }} 
  </li>
</ul>
<!-- result:
  Group name: alpha
    * player: Gene
  Group name: beta
    * player: George
    * player: Paula
  Group name: gamma
    * player: Steve
    * player: Scruath
于 2014-07-30T10:22:22.367 に答える