ui.bootstrap.typeahead:如何将$ http与去抖动结合起来

时间:2016-10-19 09:00:51

标签: javascript c# twitter-bootstrap angular-ui-bootstrap rxjs

我想利用ui.bootstrap.typeahead,因为它很棒。我正在搜索一个可能包含数百万用户的数据库,所以我真的希望能够在拨打$ http之前去掉搜索框中的击键。否则,每次击键都会导致搜索,早期击键会比以后的击键产生更慢的搜索速度,从而导致笨重的用户体验。

我目前的努力无效,看起来像这样:

JavaScript的:

angular.module("mycontrollers").controller("myCtrl", [
    "$scope", "$http", "rx", "localisationService", "close", function ($scope, $http, rx, localisationService, close) {
        var culture = localisationService.getCulture();
        function getUsersObservable(val) {
            return rx.Observable
                .fromPromise($http.get("/api/" + culture + "/usersearch", { params: { userName: val } }))
                .map(function (response) {
                    return response.data;
                });
        }
        $scope.close = close;
        $scope.$createObservableFunction("getUsers")
            .debounce(400)
            .filter(function (val) {
                return val.length > 0;
            })
            .flatMapLatest(getUsersObservable)
            .subscribe();
    }
]);

HTML:

<div class="form-group">
    <label for="the-user" localised-text-key="TheUser"></label>
    <input type="text" id="the-user" ng-model="userId" uib-typeahead="user for user in getUsers($viewValue)" typeahead-loading="loadingUsers" class="form-control" />
</div>

服务器端:

public async Task<IHttpActionResult> Get(string userName)
{
    var users = await _modelContext.Users.Where(u => u.UserName.Contains(userName)).OrderBy(u => u.UserName).Select(u => u.UserName).Take(20).ToArrayAsync();
    return Ok(users);
}

正在正确地去除输入; JavaScript开头的rx.observable将搜索结果作为字符串数组返回,并正确地对输入进行去抖动。我不确定怎么做的是将结果打包成一个可以由ui.bootstrap.typeahead正确解释的promise。

1 个答案:

答案 0 :(得分:3)

好的,我完全错过了文档

  

ng-model-options $ - ng-model的选项(参见ng-model-options directive)。目前支持debounce和getterSetter选项。

因此,该指令允许您将选项附加到它ng-model非常简单。 Angular确实。

然后,您可以使用它来设置模型值的debouce,然后通过ng-change指令调用函数。

<input type="text" id="the-user" 
    ng-model="userId" 
    ng-model-options="{'debounce': 500}" 
    ng-change="sendHttpAfterDebounce()"
    uib-typeahead="user for user in getUsers($viewValue)" typeahead- 
    loading="loadingUsers" 
    class="form-control" />

现在,您的功能(sendHttpAfterDebounce)将在您完成输入后运行500毫秒。