2013-07-15 16 views
15

Mam przypadek, w którym mam zagnieżdżone pętle, w których element potomny jest skonstruowany przez funkcję filtru, która jako argument przyjmuje rodzica. Mam też inny filtr, który po prostu dokonuje porównania tekstu. Oto przykładAngularJS - ukryj element nadrzędny, jeśli pętla podrzędna jest pusta (filtrowana)

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

Teraz moim problemem jest to, że kiedy filter:search jest stosowana i odfiltrowuje wszystkie wyniki w określonej grupie, chciałbym ukryć grupę (i nie pozostawiać pustej group.name wiszące bez elementów podrzędnych).

Nie mam materiałów w grupie jako takiej, więc nie mam tych informacji w macierzystym zakresie powtórzeń rg. Pytanie brzmi, czy istnieje sposób mogę uzyskać dostęp do zagnieżdżonego NG-repeat i zobaczyć swój licznik od rodzica i ukryć rodzica, jeżeli liczba 0.

UPDATE

Oto skrzypce że lepiej wyjaśnia sytuację: fiddle

Głównym problemem jest to, że nie chcę kojarzyć moich materiałów z grupami. Mogłabym to zrobić, gdyby nic innego nie działało, ale brzmi to jak przeciążenie (ponieważ wtedy potrzebowałbym zasadniczo filtrować wyniki dwukrotnie), gdybym mógł to zrobić po prostu sprawdzając zagnieżdżoną pętlę.

Dzięki

+0

Czy masz przykład z $ scope, filtrem i wszystkim? Byłoby mi łatwiej pomóc, gdybyśmy mieli cały obraz :) – jinxen

Odpowiedz

24

Zaproponowano znacznie czystsze rozwiązanie: HERE.

To, co musisz zrobić, to zawinąć odpowiedni obszar za pomocą ng-show/ng-if w oparciu o wyrażenie, które stosuje filtr w strukturze danych i wydobywa długość.Oto, jak to działa w twoim przykładzie:

<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> 

Umożliwia ukrycie złożonych struktur po ich opróżnieniu z powodu filtrowania, np. tabela wyników.

+4

+1 Jeżdżenie na nartach Jezusem Chrystusem, wy ludzie jesteście sprytni. DZIĘKUJEMY za to rozwiązanie! – adamdport

+0

genialna odpowiedź! –

+0

Naprawdę dobre. – Th3B0Y

1

Jeśli można prosić o materiały od grupy i można oczekiwać, aby zrobić dla każdej grupy tak, to dlaczego nie zrobić od razu, kiedy zainicjować widok i zbudować model z grupami, które mają materiały? Jeśli możesz to zrobić, możesz użyć programu ng-show, aby ukryć tylko grupy posiadające materiały.

Wydaje się, że musisz wiedzieć, że grupa ma jakieś materiały, czy nie? Oto skrzypce nie wiedząc wiele o historii w tle:

<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

widziałem tego zastosowania przypadków kilka razy, oto moje rozwiązanie:

<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> 

Można użyć $ first lub $ last w zakresie ng-repeat, aby pokazać tylko dla pierwszej i ostatniej z każdej grupy. jeśli nie ma pierwszego $, nie będzie pokazywać nazwy grupy.

właśnie wdrażane to na moim blog i zaktualizowaniu skrzypce tutaj: http://jsfiddle.net/ke793/1/

Nie jestem pewien, czy jest to najbardziej eleganckie rozwiązanie, ale wydaje się dość prosty i działa. Chciałbym zobaczyć, jak inni to rozwiązali.

Aktualizacja: właśnie zdałem sobie sprawę, że można użyć ng-if, aby zapobiec umieszczeniu nazwy grupy w domenie poza elementem $first. Trochę czystsze niż ng-hide/ng-show, który ustawia display: none na dodatkowy nagłówek za każdym razem.

+0

Tak właśnie robiłem w zupełnie innym kontekście (makumba.org dla JSP). Fajnie, nie wiedziałem, że pierwszy istnieje. –

+0

Nie sądzę, że to zadziała, jeśli musisz ukryć element zawijania, który znajduje się wewnątrz pierwszego powtórzenia ng, ale przed następnym powtórzeniem ng. Potrzebne będzie lepsze rozwiązanie. – jwize

Powiązane problemy