web-dev-qa-db-ja.com

Angular UI-Bootstrap Typeahead:結果のグループ化

AngularUI-Bootstrapを使用して先行入力を実装しています。データベースからのいくつかの値に基づいてグループ化された結果を表示する必要があります。これがサンプルシナリオです

  1. データベースには何人かのユーザーがいて、各ユーザーには「部門」があります。 1つのユーザー名を複数の部門で使用できます。
  2. エンドユーザーは名前を入力してデータベースからユーザーを検索し、先行入力リストのリストを取得します。 1つのユーザー名は複数の部門に属することができるため、異なる部門ごとにグループ化されたユーザー名を表示する必要があります。このようなもの: enter image description here
  3. 次に、ユーザーは目的のユーザー名を選択して続行できます。

存在する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

ユーザーが1つのレコードを選択します

user selects one record

部門を避けたい(この場合、string - Desc 4)ユーザーがレコードを選択したとき。

回避策なしでこのグループ化を実現する方法はありますか?または、回避策を強化する方法はありますか?

16

以前も同様の要件がありましたが、そのときの方法は次のとおりです。

プランカーの例: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>

ご覧のとおり、アイテムのプロパティfirstInGroupがtrueに設定されている場合にグループヘッダーを表示するng-ifがあります。

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

これがあなたの要件にも合うことを願っています。

29
runTarm

こちらをご覧ください 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">
2
sylwester