AngularUI-Bootstrap Typeahead: результаты группировки

Я использую typeahead, используя AngularUI-Bootstrap. Мне нужно показать результаты, сгруппированные на основе некоторых значений, поступающих из базы данных. Вот пример сценария

  • В базе данных есть некоторые пользователи, у каждого пользователя есть "Департамент". Одно имя пользователя может быть доступно в нескольких отделах.
  • Конечный пользователь вводит имена для поиска пользователей из базы данных и извлекает список в списке типов. Поскольку одно имя пользователя может принадлежать нескольким отделам, требование состоит в том, чтобы показать имена пользователей, сгруппированные по разным отделам. Что-то вроде этого: enter image description here
  • Затем пользователь может выбрать нужное имя пользователя и продолжить.

В соответствии с документацией Typeahead, представленной здесь, я не вижу возможности удовлетворить мои требования.

Я пробовал это обходное решение: всякий раз, когда массив typeahead формируется, я добавлял элемент управления к элементу массива:

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

Таким образом, по крайней мере, конечный пользователь видит отдел. Но когда я выбираю запись, выбранное значение является полным содержимым элемента массива. Ниже приведен пример скриншота для разработки:

HTML

Пользователи из локальной службы
<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>

Типы пользователей в строке

Search result

Пользователь выбирает одну запись

user selects one record

Я хочу избежать отдела (в данном случае строки - Desc 4), когда пользователь выбирает запись.

Можно ли каким-либо образом достичь этой группировки без каких-либо обходных решений? Или я могу улучшить свое обходное решение?

Ответы

Ответ 1

У меня было аналогичное требование, и вот как я это сделал в это время.

Пример Plunker: http://plnkr.co/edit/zujdouvB4bz7tFX8HaNu?p=preview

Фокус в том, чтобы установить typeahead-template-url в шаблон настраиваемого элемента:

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

Шаблон элемента, который представляет каждый элемент в выпадающем меню:

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

Как вы можете видеть, есть ng-if, чтобы показать заголовок группы, если этот элемент имеет свойство firstInGroup, установленное в true.

Свойства firstInGroup заполняются таким образом, используя 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;
}

Надеюсь, что это соответствует вашему требованию.

Ответ 2

см. здесь http://plnkr.co/edit/DmoEWzAUHGEXuHILLPBp?p=preview

вместо создания новых объектов здесь:

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

использовать шаблон создания:

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

и использовать его в директиве Typeahead

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