AngularUI-Bootstrap Typeahead:对结果进行分组

时间:2014-08-04 10:28:34

标签: javascript angularjs twitter-bootstrap typeahead

我正在使用AngularUI-Bootstrap实现typeahead。我需要根据来自数据库的一些值显示分组结果。这是一个示例场景

  1. 数据库中有一些用户,每个用户都有一个“部门”。一个用户名可以在多个部门中使用。
  2. 最终用户键入名称以从数据库中搜索用户并检索输入列表中的列表。由于一个用户名可以属于多个部门,因此要求显示按不同部门分组的用户名。像这样的东西: enter image description here
  3. 然后,用户可以选择所需的用户名并继续。
  4. 根据Typeahead文件here,我认为没有任何选项可以满足我的要求。

    我已尝试过这种解决方法:每当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)。

    有没有办法在没有任何解决方法的情况下实现这种分组?或者有什么办法可以改进我的解决方法吗?

2 个答案:

答案 0 :(得分:29)

我曾经有类似的要求,这就是我当时的做法。

示例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设置为true,则会显示一个firstInGroup来显示组标题。

使用lodashjs:

填充firstInGroup属性
$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;
}

希望这也符合您的要求。

答案 1 :(得分: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">