javascript - ui.bootstrap.typeahead : how to combine $http with debounce

标签 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 。

最佳答案

好吧,我在文档中完全错过了它

ng-model-options $ - Options for ng-model (see ng-model-options directive). Currently supports the debounce and getterSetter options.

所以该指令允许您将选项附加到它的 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 毫秒。

关于javascript - ui.bootstrap.typeahead : how to combine $http with debounce,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40126717/

相关文章:

javascript - 操作日期时出现日期问题

javascript - 使用 vue.js 更改可拖动的光标在 chrome 中不起作用

c# - WCF(或替代方案)在 Internet 上的机器上设置 Controller-worker

c# - 在 C# 中保存 XML 流表示它正在被另一个进程使用

javascript - meteor 迭代一组 session 以检查值是否已更改

html - Bootstrap 中的全宽定位?

javascript - Backbone 集合 toJSON 返回集合对象

javascript - 为什么 addChangeListener 应该在 componentDidMount 而不是 componentWillMount?

c# - 连接中的 Entity Framework 子查询

twitter-bootstrap - 水平形式 - 设置控件标签宽度的最佳方法?