2014-08-04 12 views
15

Ich implementiere Typahead mit AngularUI-Bootstrap. Ich muss die Ergebnisse basierend auf einigen Werten anzeigen, die aus der Datenbank stammen. Hier ist ein BeispielszenarioAngularUI-Bootstrap Typeahead: Gruppierungsergebnisse

  1. Es gibt einige Benutzer in der Datenbank, jeder Benutzer hat eine "Abteilung". Ein Benutzername kann in mehreren Abteilungen verfügbar sein.
  2. Der Endbenutzer gibt die Namen in die Namen ein, um Benutzer aus der Datenbank zu suchen, und ruft die Liste in der Typahead-Liste ab. Da ein Benutzername zu mehreren Abteilungen gehören kann, müssen die Benutzernamen nach verschiedenen Abteilungen gruppiert sein. Etwas wie dieses: enter image description here
  3. Dann kann der Benutzer den gewünschten Benutzernamen auswählen und fortfahren.

Gemäß der Typeahead Dokumentation vorhanden here, sehe ich jede Option nicht auf meine Anforderung gerecht zu werden.

Ich habe die diese Abhilfe versucht: Jedes Mal, wenn die typeahead Array gebildet zu werden, habe ich die Benutzer-Abteilung an das Array-Element angehängt:

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

Auf diese Weise zumindest der Endbenutzer sieht die Abteilung. Wenn ich den Datensatz auswähle, ist der ausgewählte Wert der vollständige Inhalt des Array-Elements. Im Folgenden Beispiel-Screenshot ist zu erarbeiten:

HTML

Benutzer von lokalen Service
<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> 

Benutzertypen in der Zeichenfolge

Search result

Der Benutzer wählt einen Datensatz

user selects one record

Ich mag die Abteilung vermeiden (in diesem Fall, string - Desc 4), wenn der Benutzer einen Datensatz auswählt.

Gibt es eine Möglichkeit, diese Gruppierung ohne Umgehung zu erreichen? Oder kann ich meine Problemumgehung verbessern?

+0

Haben Sie eine Lösung gefunden? Ergebnisse in Typeahead nach Kategorien gruppiert Ich versuche das auch zu tun. Können Sie bitte irgendwelche Hinweise zur Lösung vorschlagen? – Deepak

+0

Die Lösung, die ich verwendete, ist die akzeptierte Antwort. –

+0

Danke für die Antwort – Deepak

Antwort

26

Ich hatte eine ähnliche Anforderung und hier ist, wie ich es damals getan habe.

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

Der Trick ist, die typeahead-template-url zu einem benutzerdefinierten Elementvorlage zu setzen:

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

Die Elementvorlage, das jedes Element in einem Dropdown darstellen:

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

Wie Sie sehen können, gibt es eine ng-if, um einen Gruppenkopf anzuzeigen, wenn dies der Fall ist Artikel hat eine Eigenschaft firstInGroup auf True festgelegt.

Die firstInGroup Eigenschaften wie diese mit lodashjs bevölkert:

$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; 
} 

Hope this fit zu Ihrer Anforderung.

+0

Hey @runTarm, ich verstehe nicht die Funktionsweise von var gefiltert = filterFilter (Benutzer, Suche); var Ergebnisse = _ (gefiltert). Wie funktioniert das und wie benutzt man das? Bitte helfen Sie mir. – Abhishek

+0

Ich bekomme dieses Problem in der Konsole nach dem Hinzufügen der "Unterstrich" -Bibliothek. 'TypeError: _ (...). GroupBy (...). Map ist keine Funktion', geben Sie bitte eine Erklärung über' _ (gefilterte) 'Dinge. – user2518430

+1

großartige Lösung! Es gibt einen kleinen Fehler - wir müssen die 'user'-Liste vor dem Filtern kopieren:' var filtered = filterFilter (angular.copy (users), search); ' http://pnnr.co/edit/gdxBToatIHMFbH7e6QzA?p=preview – sunsay

1

bitte hier http://plnkr.co/edit/DmoEWzAUHGEXuHILLPBp?p=preview

statt neue Objekte zu schaffen, hier:

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

Verwendung Vorlage erstellen:

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

und verwenden Sie es in Ihrem typeahead Richtlinie

<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

Es ist eine wirklich nette Lösung. Upvoted :), aber habe die Antwort nicht akzeptiert, da ich nach der tatsächlichen Gruppierung suche. –

+0

@PramodKarandikar, Haben Sie gefunden, wonach Sie gesucht haben? Gruppierung von Ergebnissen in typeahead. Wenn Sie Ihre Lösung hier teilen könnten, wäre das großartig. – Deepak