Domanda

Ho un elenco di elenchi, creato con una ripetizione NG nidificata.Ogni ripetizione NG esterna contiene un div con l'etichetta della sua lista interna (ad es.: "Gruppo A").Ora sto cercando di creare un modo per evitare di mostrare questa etichetta se la lista interna è vuota a causa del filtraggio (applicato da un searchtext di input)

Ecco un pinkeer che spiega il mio problema e la mia soluzione tentata: PLNKR

Avere una funzione "pesante" come Isgrouprempty sembra estremamente ingombrante - c'è un modo per farlo in una moda molto più semplice?Stavo giocando con l'idea di spostare l'etichetta all'interno dell'interiore NG-ripetizione e avere ng-show="$first" ma non sembra fantastico

È stato utile?

Soluzione

Ho finito con la seguente soluzione che ha funzionato perfettamente. PLNKR

Impostando una variabile nella ripetizione NG interna sono in grado di valutare NG-Show in base a questa variabile Lunghezza come:

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

Altri suggerimenti

Puoi sfruttare ng-init, in questo modo chiamerai il filtro solo una volta:

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

Di solito non è una buona pratica usare ng-init da non dove, ma immagino che risolva il filtro due volte. Un altro modo è quello di utilizzare il filtro tramite JavaScript - è possibile iniettare $ Filtro e recuperare "Filtro" $filter('filter') nel tuo controller, chiamandolo con Gruppo come primo argomento, il filtroFN come secondo e memorizza il suo risultato nel tuo scopo.

.

Ho usato quanto segue:

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

Controllo se un array ha una lunghezza di 0 non è un funzionamento costoso.Se si desidera visualizzare solo gli elenchi che hanno elementi, mettere un filtro sull'array esterno che prende una serie di array e restituisce solo gli array che hanno una lunghezza diversa da 0.

Puoi anche nascondere il div interno se l'array== false.

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

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

Il tuo plunkr era piuttosto complicato e difficile da inviare attraverso così ho ricreato quello che volevi usare un violino.L'idea generale alla base del mio approccio è quella di filtrare gli elementi dall'array, non nell'array sub.E eseguire solo gli elementi filtrati quando il testo cambia.Quindi ecco il markup:

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

Ed Ecco il codice:

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 ragione per cui sto creando un nuovo array e non usando un filtro effettivo per rimuovere i risultati è che l'angolare non piace creare array dinamiche al volo nei filtri.Questo perché non assegna $$ Hashkey e le cose non solo non si allineano correttamente quando il controllo sporco.Ho avuto l'idea di come fare ciò di cui avevi bisogno da questo argomento sulla questione: https://groups.google.com/forum/#!Topic/angular/ieiqok-ykpu

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top