2013-07-15 11 views
15

親を引数とするフィルタ関数によって子ループが構築されたネストされたループがあるケースがあります。私はまた、テキスト比較だけのフィルタがあります。ここでは例AngularJS - 子ループが空(フィルタリングされている場合)の親要素を隠す

<div ng-repeat="group in groups"> 
    {{group.name}} 
    <div ng-repeat="material in materials | filter:filterByGroup(group) | filter:search "> 
    {{material.name}} 
    </div> 
</div> 

は今、私の問題はfilter:searchが適用され、それが特定のグループ内のすべての結果をフィルタリングしたとき、私は子要素なしで空group.nameぶら下げを残してグループを非表示にする(としないことです)。

私は自分自身のグループ内の資料を持っていないので、その情報は親ng-repeatスコープにはありません。そのカウントが0

ここでUPDATE

がより良いフィドルであるならば、私は、ネストされたNG-繰り返しにアクセスし、親からそのカウントを参照し、親を隠すことができる方法があるかどうかの質問です状況を説明します:fiddle

主な問題は、自分のマテリアルをグループに関連付けることを望まないということです。それ以外のものは動作しませんが、ネストされたループをチェックするだけで、結果が2回フィルタリングされる必要があるので、オーバーロードのように聞こえます。

おかげ

+0

$ scope、filter、allの例はありますか? – jinxen

答えて

24

もっと清潔な解決策が提案されたHERE

データ構造にフィルタを適用し、長さを抽出する式に基づいて、該当する領域をng-show/ng-ifで囲む必要があります。ここでは、それはあなたの例ではどのように動作するかです:

<div ng-show="(materials | filter:filterByGroup(group)).length"> 
    <div ng-repeat="group in groups"> 
     {{group.name}} 
     <div ng-repeat="material in materials | filter:filterByGroup(group) | filter:search "> 
     {{material.name}} 
     </div> 
    </div> 
    </div> 

これは、例えば、彼らはフィルタリングによる空です一度あなたが複雑な構造を非表示にすることができます結果の表

+4

+1イエス・ジェットスキー・キリスト、あなたは人々がとても賢明な顔をしています。この解決策をありがとうございます! – adamdport

+0

華麗な答え! –

+0

確かに本当に良い。 – Th3B0Y

1

あなたがグループで資料を求めることができますし、とにかく各グループのためにそれを行うことを期待する場合は、ビューを初期化し、材料を持っているグループでモデルを構築する際に、なぜすぐということをしませんか?これを行うことができれば、ng-showを使ってマテリアルを持つグループだけを隠すことができます。

グループには素材があるとか、どういうわけか分かりません。ここではフィドルが背景の物語の多くを知らなくても、です:

<div ng-controller="MyCtrl"> 

    <div ng-repeat="group in groups"> 
     <div ng-show="groupHasMaterials(group)">{{group.name}}</div> 
     <div ng-repeat="material in materialsByGroup(group)"> 
      <div>{{material.name}}</div> 
     </div> 
    </div> 

</div> 


<script> 
var myApp = angular.module('myApp',[]); 

function MyCtrl($scope) { 

    var groups = [ 
     {'name':'group one'}, 
     {'name':'group two'} 
    ]; 

    var materials = [ 
     {'name':'material1'}, 
     {'name':'material2'}, 
     {'name':'material3'} 
    ]; 

    $scope.groups = groups; 
    $scope.materials = materials; 

    $scope.groupHasMaterials = function(group){ 
     return $scope.materialsByGroup(group).length > 0;  
    } 

    $scope.materialsByGroup = function(group){ 
     return group.name === 'group one' 
      ? [materials[0], materials[1]] 
      : []; 
    } 
} 
</script> 

fiddle with groups

8

私はこのユースケースを数回見てきた、ここに私のソリューションです:

<div ng-repeat="group in groups"> 
    <div ng-repeat="material in materials | filter:filterByGroup(group) | filter:search "> 
     <span ng-show="$first"> 
      {{group.name}}<br/> 
     </span> 
     {{material.name}} 
    </div> 
</div> 

あなたは$を使用することができますng-repeatの範囲内のfirstまたは$ lastは、各グループの最初と最後にのみ表示されます。 $ firstがなければ、グループ名は表示されません。

私はちょうど私のblog上でこれを実装し、ここにあなたのフィドルを更新:http://jsfiddle.net/ke793/1/

私は、これが最もエレガントなソリューションであるかどうかわからないんだけど、それはかなり単純なようで、それが動作します。私は他の人がこれをどのように解決したかを見たいと思う。

更新:$first要素の外側のグループ名がグループ名に全く当たらないようにするには、ng-ifを使用することができます。毎回余分なヘッダーにdisplay: noneを設定するng-hide/ng-showよりも少しクリーナーです。

+0

これはまったく別のコンテキスト(JSP用のmakumba.orgフレームワーク)でこれを行う方法とまったく同じです。クール、$が最初に存在したことを知らなかった。 –

+0

最初のng-repeatの中で、次のng-repeatの前にあるラップ要素を非表示にする必要がある場合、これはうまくいかないと思います。より良い解決策が必要になります。 – jwize

関連する問題