Ocultar elemento principal en DOM cuando los niños están vacíos

<div> <h1>Birds</h1> <ul> <li ng-if="bird.type === 'bird'" ng-repeat="bird in creatures">{{bird.name}}</li> </ul> </div> 

Tengo una respuesta del server y quiero ponerlo en la list. Pero cuando la list está vacía, necesito ocultar este contenedor div. Por ejemplo, si bird.type === 'bird' no está en la matriz, quiero ocultar div. Pero quiero usar bird después de ng-repeat, así que no puedo hacer ng-if="bird.type === 'bird'" en div . ¿Puedo verificar si li está vacío, luego ocultar el div?

Ejemplo de Plunkr

AngularJS ng-repeat handle empty list case – No es lo mismo. No quiero ocultar li si está vacío, quiero ocultar parent donde tengo h1 – cuando li está vacío.

Usted podría hacer lo siguiente:

 <div ng-if="hasBirds(creatures)"> <h1>Birds</h1> <ul> <li ng-if="bird.type === 'bird'" ng-repeat="bird in creatures">{{bird.name}}</li> </ul> </div> 

Y luego en controller / directiva puede agregar la function hasBirds .

 $scope.hasBirds = function(list){ return list.filter(function(item){return item.type === 'bird'}).length > 0; } 

Esta function de hasBirds sería llamada con frecuencia, pero te permitiría ocultar / mostrar que el encabezado de las aves existe.

En su ejemplo, le aconsejo que use un filter en lugar de usar "ng-if", debe crear un filter como:

 angular.module('moduleName').filter(birdsFilter); function birdsFilter(creature) { return creature.type == 'bird'; } 

Con el filter puedes reescribir tu código así:

 <div ng-hide="birds.length"> <h1>Birds</h1> <ul> <li ng-repeat="bird in birds = (creatures | filter:birdsFilter)">{{bird.name}}</li> </ul> </div> 

OMI, varias de estas respuestas funcionarán. Pero ninguno de ellos está idealmente optimizado. Yo recomendaría filtrar sus datos en su function controller / postlink.

 $scope.animals = { dogs: $scope.creates.filter(function(a){return a.type == 'dog'}), cats: $scope.creates.filter(function(a){return a.type == 'cat'}), birds: $scope.creates.filter(function(a){return a.type == 'bird'}), fishes: $scope.creates.filter(function(a){return a.type == 'fish'}) }; 

De esta forma, solo procesaría la matriz de criaturas una vez, en un solo lugar. El ciclo de resumen nunca tendría que volver a evaluar la matriz para ver si necesitaba actualizar el DOM. Esto es lo que marca con el aspecto entonces:

 <div ng-if="animals.birds.length"> <h1>Birds</h1> <ul> <li ng-repeat="bird in animals.birds">{{bird.name}}</li> </ul> </div> 

Debe filtrar la list según el tipo, almacenar los elementos filtrados en una propiedad de ámbito y luego usar esa propiedad para mostrar u ocultar el div.

 <div ng-show="birds.length"> <h1>Birds</h1> <ul> <li ng-repeat="bird in creatures | filter:birdType as birds">{{bird.name}} </li> </ul> </div> 

Luego, implemente la function de filter birdType en su controller:

 $scope.birdType = function(creature) { return creature.type === 'bird'; }; 

Usando ng-show="cats.length" para hacer que los div desaparezcan si la longitud es cero.

Filtre en línea según la propiedad del object como cat in creatures | filter:{type: 'cat'} as cats cat in creatures | filter:{type: 'cat'} as cats como se explica en esta publicación SO .

EJEMPLO DE TRABAJO:

 var app = angular.module('App', []); app.filter(birdsFilter); function birdsFilter(creature) { return creature.type == 'bird'; } app.controller('Ctrl', function($scope) { $scope.creatures = [ { name : 'Cho-cho', type : 'bird' }, { name : 'Floo-floo', type : 'dog' }, { name : 'Pou-pou', type : 'bird' }, { name : 'Oop-flup', type : 'bird' }, { name : 'Chio-mio', type : 'cat' }, { name : 'Floo-floo', type : 'dog' }, { name : 'Loo-Li', type : 'dog' }, { name : 'Pops-Mops', type : 'bird' }, { name : 'Boo-Moo', type : 'dog' }, { name : 'Iop-Pio', type : 'dog' }, { name : 'Floop-cho', type : 'bird' } ] }); 
 <!DOCTYPE html> <html ng-app="App"> <head> <script data-require="angularjs@1.5.7" data-semver="1.5.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script> <link rel="stylesheet" href="style.css" /> <script src="script.js"></script> </head> <body ng-controller="Ctrl"> <div ng-show="birds.length"> <h1>Birds</h1> <ul> <li ng-repeat="bird in creatures | filter:{type: 'bird'} as birds">{{bird.name}} </li> </ul> </div> <div ng-show="dogs.length"> <h1>Dogs</h1> <ul> <li ng-repeat="dog in creatures | filter:{type: 'dog'} as dogs">{{dog.name}} </li> </ul> </div> <div ng-show="cats.length"> <h1>Cats</h1> <ul> <li ng-repeat="cat in creatures | filter:{type: 'cat'} as cats">{{cat.name}} </li> </ul> </div> <div ng-show="fishes.length"> <h1>Fish</h1> <ul> <li ng-repeat="fish in creatures | filter:{type: 'fish'} as fishes">{{fish.name}} </li> </ul> </div> </body> </html>