【发布时间】: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