ui.bootstrap.typeahead:如何结合 $http 和 debounce [英] ui.bootstrap.typeahead: how to combine $http with debounce

查看:19
本文介绍了ui.bootstrap.typeahead:如何结合 $http 和 debounce的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想利用 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();函数 getUsersObservable(val) {返回 rx.Observable.fromPromise($http.get("/api/" + culture + "/usersearch", { params: { userName: val } })).map(函数(响应){返回 response.data;});}$scope.close = 关闭;$scope.$createObservableFunction("getUsers").去抖动(400).filter(函数(val){返回 val.length >0;}).flatMapLatest(getUsersObservable).订阅();}]);

HTML:

<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"/>

服务器端:

公共异步任务获取(字符串用户名){var users = await _modelContext.Users.Where(u => u.UserName.Contains(userName)).OrderBy(u => u.UserName).Select(u => u.UserName).Take(20).ToArrayAsync();返回确定(用户);}

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

解决方案

好的,我完全错过了文档

<块引用>

ng-model-options $ - ng-model 的选项(参见 ng-model-选项指令).目前支持 debounce 和 getterSetter 选项.

因此该指令允许您将选项附加到它的 ng-model,就像普通的 Angular 一样.

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

现在您的函数 (sendHttpAfterDebounce) 将在您完成输入后运行 500 毫秒.

I'd like to take advantage of ui.bootstrap.typeahead because it is excellent. I'm implementing a search of a database that could contain millions of users, so I would really like to be able to debounce keystrokes in the search box before making a call to $http. Otherwise every keystroke will result in a search, and early keystrokes will generate slower searches than later keystrokes, resulting in a clunky user experience.

My current effort, which doesn't work, looks like this:

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>

Server Side:

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

The input is being debounced correctly; the rx.observable at the start of the JavaScript is returning the search results as an array of strings, and debouncing the input correctly. What I'm not sure how to do is to package the results up into a promise that can be interpreted correctly by ui.bootstrap.typeahead.

解决方案

Ok, I totally missed it in the docs

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

So the directive allows you to attach options to it's ng-model very much as plain ol' Angular does.

So you can then use it to set a debouce to your model value, and then call a function through the ng-change directive.

<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" />

Now your function (sendHttpAfterDebounce) will run 500 milliseconds after you're done typing.

这篇关于ui.bootstrap.typeahead:如何结合 $http 和 debounce的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆