tablas dinamicas con array angularjs angularjs-ng-repeat

angularjs - dinamicas - ¿Cómo solo muestro un elemento si ng-repeat anidado no está vacío?



ng-repeat table (6)

Tengo una Lista de listas, creada con una repetición ng anidada. Cada ng-repeat externa contiene un div con la etiqueta de su lista interna (p. Ej .: "Grupo A"). Ahora intento crear una forma de evitar mostrar esta etiqueta si la lista interna está vacía debido al filtrado (Aplicado por un texto de búsqueda de entrada)

Aquí hay un plunker explicando mi problema y mi intento de solución: Plnkr

Tener una función ''pesada'' como isGroupEmpty parece extremadamente engorrosa. ¿Hay alguna manera de hacer esto de una manera mucho más simple? Estaba jugando con la idea de mover la etiqueta dentro de la repetición ng interna y tener ng-show="$first" pero no se ve muy bien


Solo modifiqué ligeramente tu list-widget.html , lo veo en acción: plunkr

La idea es simple: use el mismo filtro para ng-show :

<div ng-show="group | filter:searchText">{{ key }}</div>

La etiqueta será visible solo si hay algunos elementos sin filtrar.

En mi ejemplo, estoy usando searchText para filtro porque no estoy familiarizado con CoffeeScript.


Terminé con la siguiente solución que funcionó a la perfección. Plnkr

Al establecer una variable en la repetición ng interna, pude evaluar ng-show en función de la longitud de estas variables, así:

<input ng-model=''searchText''/> <span ng-show=''filtered.length > 0''> <ul> <li ng-repeat=''el in filtered = (model | filter:searchText)''> <div>{{el.label}}</div> </li> </ul> </span>


Tu plunkr fue bastante complicado y difícil de eliminar, así que recreé lo que querías usando un violín. La idea general detrás de mi enfoque es filtrar los elementos de la matriz, no la matriz secundaria. Y solo hacen los artículos filtrados cuando el texto cambia. Así que aquí está el marcado:

<div ng-app="app"> <div ng-controller="ParentCtrl"> <input data-ng-model="filterText" data-ng-change="updateTypes()" /> <div data-ng-repeat="type in filteredTypes"> {{ type.name }} <ul> <li style="margin-left:20px;" data-ng-repeat="entry in type.entries"> - {{ entry.name }} </li> </ul> </div> </div> </div>

Y aquí está el código:

angular.module(''app'', []) function ParentCtrl($scope){ $scope.filterText = ""; $scope.types = [ { name: "type1", entries: [{ name: "name1"}, { name: "name2"}, { name: "name3"}]}, { name: "type2", entries: [{ name: "name1"}, { name: "name3"}, { name: "name3"}]}, { name: "type3", entries: [{ name: "name1"}, { name: "name2"}, { name: "name5"}]}, { name: "type4", entries: [{ name: "name4"}, { name: "name2"}, { name: "name3"}]} ]; $scope.filteredTypes = []; $scope.updateTypes = function(){ $scope.filteredTypes.length = 0; for(var x = 0; x < $scope.types.length; x++){ if($scope.filterText === ""){ $scope.filteredTypes.push($scope.types[x]); } else{ var entries = []; for(var y = 0; y < $scope.types[x].entries.length; y++){ if($scope.types[x].entries[y].name.indexOf($scope.filterText) !== -1){ entries.push($scope.types[x].entries[y]); } } if(entries.length > 0){ $scope.filteredTypes.push({ name: $scope.types[x].name, entries: entries }); } } } } $scope.updateTypes(); }

Fiddle : http://jsfiddle.net/2hRws/

La razón por la que estoy creando una nueva matriz y no usando un filtro real para eliminar los resultados es que a angular no le gusta crear matrices dinámicas sobre la marcha en los filtros. Esto se debe a que no asigna $$ hashKey y las cosas simplemente no se alinean correctamente cuando se realiza una comprobación sucia. Obtuve la idea de cómo hacer lo que necesitaba de este tema al respecto: https://groups.google.com/forum/#!topic/angular/IEIQok-YkpU


Usé lo siguiente:

<ul> <li ng-repeat="menuItem in menuItems"><a href="Javascript:void(0);"><span class="fa {{menuItem.icon}} fa-lg"></span>{{menuItem.itemName}}</a> <span ng-show=''menuItem.subItems.length > 0''> <ul> <li ng-repeat="subItem in menuItem.subItems"><a href="Javascript:void(0);">{{subItem.itemName}}</a></li> </ul> </span> </li>



podría aprovechar ng-init , de esa manera llamará al filtro solo una vez:

<div ng-repeat=''(key,group) in model''> <div ng-init="filtered = (group | filter:filterFn)"></div> <div ng-show="filtered.length !== 0"> <div>{{key}}</div> <ul> <li ng-repeat="el in filtered"> <div>{{el.label}}</div> </li> </ul> </div> </div>

Usualmente no es una buena práctica usar ng-init de ninguna parte, pero supongo que resuelve llamar al filtro dos veces. Otra forma es usar el filtro mediante javascript: puede inyectar $ filter y recuperar ''filter'' $filter(''filter'') en su controlador, llamándolo con group como primer argumento, filterFn como segundo y almacenar su resultado en su alcance