2016-10-19 10 views
1

これは優れているため、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を参照してください) -

+0

[非同期検証ツール](http://stackoverflow.com/documentation/angularjs/3979/form-validation/22099/async-validators#t=201610190950349255524)を使用してみましたか? – svarog

+0

ありがとうございます - 私はこれらのことを知らなかったので、彼らが利用可能であることを確認することは良いことです。この場合、デバウンス(これは、各キーストロークではなく、400ms後にサーバーにコールを送信することを意味します)をサポートしていないため、実際には必要としません。私が本当に後にしているのは、Angular rx debounceをAngular UI Bootstrap先読み機能と共にうまく動作させる方法です。 –

+0

私がこの例を書いたとき、私は既存のコードを取りました。私はそれに取り組み、それを単純化しました。オリジナルでは、アンダースコアライブラリから '_.debouce'関数を使用しました。 – svarog

答えて

3

[OK]を、私は完全にドキュメント

NG-モデル・オプションの$でそれを逃しました。現在、debounceおよびgetterSetterオプションをサポートしています。

この指示文では、オプションを添付することができます。ng-modelは非常によく知られています。

それで、それを使用してモデル値にデバウンスを設定してから、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ミリ秒を実行します。

関連する問題