【问题标题】:ui.bootstrap.typeahead: how to combine $http with debounceui.bootstrap.typeahead:如何将 $http 与 debounce 结合使用
【发布时间】:2017-02-28 19:37:45
【问题描述】:

我想利用 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 正确解释的承诺。

【问题讨论】:

  • 您是否尝试过使用Async Validators
  • 谢谢——我不知道这些,所以很高兴看到它们可用。在这种情况下,它并没有真正满足我的需要,因为它不提供任何去抖动支持(这意味着在 400 毫秒后向服务器发送调用,而不是在每次击键时)。我真正追求的是一种让 Angular rx debounce 与 Angular UI Bootstrap typeahead 功能一起工作的方法。
  • 当我编写示例时,我采用了我处理过的现有代码并对其进行了简化。在原文中,我使用了下划线库中的_.debouce 函数。
  • 哦,您还可以使用ng-model-options 设置值更新时的debouce。文档涵盖了

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


【解决方案1】:

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

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 毫秒。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-11
    • 2012-04-01
    • 2017-06-13
    • 2019-02-09
    • 2012-08-21
    • 2018-02-23
    • 2017-02-10
    相关资源
    最近更新 更多