AngularJS コントローラーが API を呼び出して、メンバーのリストを取得しています。API は、年齢範囲、名前検索、郵便番号などの複数のフィルターを使用してクエリを実行できます。
私が達成しようとしているのは、検索が非常に高速であるとユーザーに感じさせることです。そのため、ユーザーがフィルタリングしている間、フィルターの変更を $watch しています。フィルターが変更されると、ユーザーが「検索」をクリックするのを待つのではなく、すぐに新しい検索 API 呼び出しを行います。
ユーザーがフィルタリングを終了して「検索」をクリックすると、システムはすでに検索を終了し、検索結果を出力できるようになるという考え方です。
問題:ユーザーが「検索」をクリックしてpublish()
関数が呼び出されたとき、現在進行中の API 検索がないことを確認する必要があり、進行中の場合は終了するまで待ちます。次に、検索結果を非表示から表示に公開しmemberslist.temp
ますmemberslist.members
。
// Current code works, except the publish function. See the TODO:
app.controller('SearchCtrl', ['$scope', 'Restangular', '$timeout', function($scope, Restangular, $timeout) {
// Pushes prefetched search results over to the visible search results
// TODO: Check if search is ongoing...
$scope.publish = function() {
$scope.memberslist.members = $scope.memberslist.temp;
};
// Watch filters for changes
var searchTimer = false;
var previousSearch = [$scope.name, $scope.minAge, $scope.maxAge];
$scope.$watch('[name, minAge, maxAge]', function(newVal, oldVal, scope){
if (searchTimer) {
$timeout.cancel(searchTimer);
}
// Do search only after the user has stopped typing for 400 ms
searchTimer = $timeout(function(){
if (!_.isEqual(newVal, previousSearch)) {
previousSearch = newVal;
scope.search();
}
}, 400);
}, true);
$scope.search = function() {
var query_params = {
name: $scope.name,
price_min: $scope.minAge,
price_max: $scope.maxAge
};
Restangular.all('members').getList(query_params)
.then(function(members){
$scope.memberslist.temp = members;
});
};
}]);
私が最初に考えたのは、isSearching = true のような変数を設定し、検索呼び出しが結果を返したら、それを false に戻すことでした。しかし、それを機能させることはできないようです。