これは優れているため、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で正しく解釈できる約束事にパッケージ化することです。 NG-モデルのオプション(ng-model-options directiveを参照してください) -
[非同期検証ツール](http://stackoverflow.com/documentation/angularjs/3979/form-validation/22099/async-validators#t=201610190950349255524)を使用してみましたか? – svarog
ありがとうございます - 私はこれらのことを知らなかったので、彼らが利用可能であることを確認することは良いことです。この場合、デバウンス(これは、各キーストロークではなく、400ms後にサーバーにコールを送信することを意味します)をサポートしていないため、実際には必要としません。私が本当に後にしているのは、Angular rx debounceをAngular UI Bootstrap先読み機能と共にうまく動作させる方法です。 –
私がこの例を書いたとき、私は既存のコードを取りました。私はそれに取り組み、それを単純化しました。オリジナルでは、アンダースコアライブラリから '_.debouce'関数を使用しました。 – svarog