Comment puis-je afficher uniquement un élément si imbriqués ng-repeat n'est pas vide?

StackOverflow https://stackoverflow.com//questions/20002481

  •  20-12-2019
  •  | 
  •  

Question

J'ai une Liste de listes, créé avec un imbriquée ng-repeat.Chaque externe ng-repeat contient un div avec l'étiquette de sa liste interne (par exemple:"Groupe A").Je vais maintenant essayer de créer un moyen pour éviter de montrer cette étiquette si l'intérieure de la liste est vide à cause d'un filtrage(Appliquée par une entrée texterecherché)

Voici une plunker expliquant mon problème et ma tentative de solution : Plnkr

Avoir un "lourds" de la fonction comme isGroupEmpty semble extrêmement lourdes - Est-il un moyen de le faire dans une beaucoup plus simple de la mode?J'ai été jongle avec l'idée d'aller de l'étiquette à l'intérieur de l'intérieur ng-repeat et avoir ng-show="$first" mais il n'a pas l'air grand

Était-ce utile?

La solution

J'ai fini avec la solution suivante qui a parfaitement fonctionné. Plnkr

Par définition d'une variable à l'intérieur de ng-repeat, j'ai été en mesure d'évaluer ng-show basé sur ces variables longueur de la sorte :

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

Autres conseils

vous pourriez tirer parti de ng-init, de cette façon, vous appelez le filtre qu'une seule fois:

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

habituellement, il n'est pas une bonne pratique à utiliser ng-init de pas où, mais je suppose qu'il résout en appelant le filtre deux fois.Une autre méthode consiste à utiliser le filtre à l'aide de javascript - vous pourrait injecter $filtrer et récupérer des "filtres" $filter('filter') dans votre contrôleur, en l'appelant avec le groupe en tant que premier argument, le filterFn comme son second, et de stocker le résultat dans votre périmètre.

J'ai utilisé les éléments suivants:

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

vérifier si un tableau a une longueur de 0 n'est pas une opération coûteuse.si vous souhaitez afficher uniquement les listes qui ont l'élément, mettre un filtre sur l'extérieur du tableau qui prend un tableau de tableaux et renvoie uniquement les tableaux qui ont une longueur différente de 0.

vous pouvez également masquer l'intérieur de la div, si l'array == false.

http://plnkr.co/edit/gist:3510140

http://plnkr.co/edit/Gr5uPnRDbRfUYq0ILhmG?p=preview

Votre plunkr était assez compliqué et difficile de mauvaises herbes à travers donc j'ai re-créé ce que l'on veut à l'aide d'un violon.L'idée générale derrière mon approche est de filtrer les éléments de tableau, pas le sous-tableau.Et seulement les éléments filtrés lors de la modification du texte.Alors, voici la syntaxe:

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

Et voici le code:

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();
}

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

La raison pour laquelle je suis en création d'un nouveau tableau et non pas à l'aide d'un filtre pour supprimer les résultats, c'est que angulaires n'aime pas la création de tableaux dynamiques à la volée dans les filtres.C'est parce qu'il ne veut pas céder $$hashKey et les choses ne sont pas alignés correctement quand il est sale vérification.J'ai eu l'idée de comment faire ce que vous avez besoin à partir de cette rubrique sur le sujet: https://groups.google.com/forum/#!topic/angulaire/IEIQok-YkpU

J'ai légèrement modifié votre list-widget.html, le voir en action: plunkr

L'idée est simple: utiliser le même filtre pour ng-show:

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

L'étiquette est visible uniquement si il y a certains éléments non filtrée.

Dans mon exemple, je suis en utilisant searchText pour le filtre, parce que je ne suis pas familier avec CoffeeScript.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top