2014-08-04 13 views
15

Sto implementando typeahead utilizzando AngularUI-Bootstrap. Devo mostrare i risultati raggruppati in base ad alcuni valori provenienti dal database. Ecco uno scenario di esempioAngularUI-Bootstrap Typeahead: Raggruppamento dei risultati

  1. Ci sono alcuni utenti nel database, ogni utente ha un "Dipartimento". Un nome utente può essere disponibile in più reparti.
  2. L'utente finale digita i nomi per cercare utenti dal database e recupera l'elenco nell'elenco dei caratteri. Poiché un nome utente può appartenere a più reparti, il requisito è mostrare i nomi utente raggruppati in dipartimenti diversi. Qualcosa del genere: enter image description here
  3. Quindi l'utente può selezionare il nome utente desiderato e procedere.

Come per la Typeahead documentazione presente here, non vedo alcuna possibilità di soddisfare la mia richiesta.

Ho provato il questa soluzione: Quando l'array typeahead si sta formata, io allegate dipartimento dell'utente all'elemento dell'array:

$scope.fetchUsers = function(val) { 
     console.log("Entered fetchUsers function"); 
     return $http.get("http://localhost:8080/TestWeb/users", { 
      params : { 
       username : val 
      } 
     }).then(function(res) { 
      console.log("Response:",res); 
      var users = []; 
      angular.forEach(res.data, function(item) { 
       users.push(item.UserName + " - " + item.UserDepartment); 
      }); 
      console.log("users=",users); 
      return users; 
     }); 
    }; 

In questo modo, almeno l'utente finale vede dipartimento. Ma quando seleziono il record, il valore selezionato è il contenuto completo dell'elemento dell'array. Di seguito è riportato screenshot di esempio per elaborare:

HTML

utenti dal servizio locale
<pre>Model: {{userList | json}}</pre> 
<input type="text" ng-model="userList" placeholder="Users loaded from local database" 
typeahead="username for username in fetchUsers($viewValue)" 
typeahead-loading="loadingUsers" class="form-control"> 
<i ng-show="loadingUsers" class="glyphicon glyphicon-refresh"></i> 

utente digita la stringa

Search result

L'utente seleziona un record

user selects one record

voglio evitare il reparto (in questo caso, stringa - Desc 4) quando l'utente seleziona un record.

C'è un modo per ottenere questo raggruppamento senza alcuna soluzione? O c'è un modo per migliorare la mia soluzione alternativa?

+0

Hai trovato qualche soluzione di questo. mostrando i risultati in Typeahead raggruppati per categoria. Sto anche cercando di fare lo stesso. Potete suggerire qualsiasi suggerimento per una soluzione? – Deepak

+0

La soluzione che ho usato è la risposta accettata. –

+0

Grazie per aver risposto – Deepak

risposta

26

Avevo un requisito simile ed ecco come l'ho fatto quella volta.

Esempio Plunker:http://plnkr.co/edit/zujdouvB4bz7tFX8HaNu?p=preview

Il trucco è quello di impostare il typeahead-template-url ad un modello di elemento personalizzato:

<input type="text" class="form-control" placeholder="Users loaded from local database" 
    ng-model="selectedUser" 
    typeahead="user as user.name for user in getUsers($viewValue)" 
    typeahead-template-url="typeahead-item.html" /> 

Il modello di elemento, questo rappresentano ogni elemento in un menu a tendina:

<div class="typeahead-group-header" ng-if="match.model.firstInGroup">Desc {{match.model.group}}</div> 
<a> 
    <span ng-bind-html="match.label | typeaheadHighlight:query"></span> 
</a> 

Come potete vedere, c'è un ng-if per mostrare un'intestazione di gruppo se quello l'articolo ha una proprietà firstInGroup impostata su true.

Le firstInGroup proprietà vengono compilate come questo utilizzando lodashjs:

$scope.getUsers = function (search) { 
    var filtered = filterFilter(users, search); 

    var results = _(filtered) 
    .groupBy('group') 
    .map(function (g) { 
     g[0].firstInGroup = true; // the first item in each group 
     return g; 
    }) 
    .flatten() 
    .value(); 

    return results; 
} 

Spero che questo adatta al vostro requisito anche.

+0

Ehi @runTarm, non capisco il funzionamento di var filtered = filterFilter (users, search); var results = _ (filtrato). Qual è il funzionamento di questo e come usarlo, per favore aiutatemi. – Abhishek

+0

Ho riscontrato questo problema in console dopo aver aggiunto la libreria 'underscore'. 'TypeError: _ (...). GroupBy (...). Map is not a function', per favore fornisci alcune spiegazioni sulle cose' _ (filtered) '. – user2518430

+1

ottima soluzione! C'è un piccolo bug - abbiamo bisogno di copiare l'elenco degli utenti prima del filtraggio: 'var filtered = filterFilter (angular.copy (users), search);' http://plnkr.co/edit/gdxBToatIHMFbH7e6QzA?p=preview – sunsay

1

vedere qui http://plnkr.co/edit/DmoEWzAUHGEXuHILLPBp?p=preview

invece di creare nuovi oggetti qui:

angular.forEach(res.data, function(item) { 
       users.push(item.UserName + " - " + item.UserDepartment); 
      }); 

uso creare template:

<script type="text/ng-template" id="customTemplate.html"> 
    <a> {{ match.model.name}} - department : {{match.model.dept}}</a> 
    </script> 

e utilizzarlo nella vostra typeahead direttiva

<input type="text" ng-model="selected" 
typeahead="user.name as user for user in users | filter:$viewValue | limitTo:8" class="form-control" 
typeahead-template-url="customTemplate.html"> 
+0

È davvero una bella soluzione. In svantaggio :), ma non ho accettato la risposta poiché sto cercando un raggruppamento effettivo. –

+0

@PramodKarandikar, hai trovato quello che stavi cercando? Raggruppando i risultati in typeahead. Se potessi condividere la tua soluzione qui sarebbe fantastico. – Deepak

Problemi correlati