Fixes: U4-5977 The debounce timeout on the main search is too big which produces a lag in searching & U4-5994 Global search needs to only show results for the 'last' search request made and ignore previous ones

This commit is contained in:
Shannon
2014-12-16 15:50:54 +11:00
parent d564866b07
commit 0807597a3c
4 changed files with 84 additions and 38 deletions

View File

@@ -5,7 +5,7 @@
* @element ANY
* @restrict E
**/
function treeSearchBox(localizationService, searchService) {
function treeSearchBox(localizationService, searchService, $q) {
return {
scope: {
searchFromId: "@",
@@ -34,19 +34,37 @@ function treeSearchBox(localizationService, searchService) {
scope.showSearch = "false";
}
//used to cancel any request in progress if another one needs to take it's place
var canceler = null;
function performSearch() {
if (scope.term) {
scope.results = [];
//a canceler exists, so perform the cancelation operation and reset
if (canceler) {
console.log("CANCELED!");
canceler.resolve();
canceler = $q.defer();
}
else {
canceler = $q.defer();
}
var searchArgs = {
term: scope.term
term: scope.term,
canceler: canceler
};
//append a start node context if there is one
if (scope.searchFromId) {
searchArgs["searchFrom"] = scope.searchFromId;
}
searcher(searchArgs).then(function (data) {
scope.searchCallback(data);
//set back to null so it can be re-created
canceler = null;
});
}
}
@@ -57,7 +75,7 @@ function treeSearchBox(localizationService, searchService) {
performSearch();
}
});
}, 20));
}, 200));
var searcher = searchService.searchContent;
//search

View File

@@ -263,20 +263,26 @@ function entityResource($q, $http, umbRequestHelper) {
* @returns {Promise} resourcePromise object containing the entity array.
*
*/
search: function (query, type, searchFrom) {
search: function (query, type, searchFrom, canceler) {
var args = [{ query: query }, { type: type }];
if (searchFrom) {
args.push({ searchFrom: searchFrom });
}
var httpConfig = {};
if (canceler) {
httpConfig["timeout"] = canceler;
}
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"entityApiBaseUrl",
"Search",
args)),
'Failed to retrieve entity data for query ' + query);
$http.get(
umbRequestHelper.getApiUrl(
"entityApiBaseUrl",
"Search",
args),
httpConfig),
'Failed to retrieve entity data for query ' + query);
},
@@ -301,15 +307,21 @@ function entityResource($q, $http, umbRequestHelper) {
* @returns {Promise} resourcePromise object containing the entity array.
*
*/
searchAll: function (query) {
searchAll: function (query, canceler) {
var httpConfig = {};
if (canceler) {
httpConfig["timeout"] = canceler;
}
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"entityApiBaseUrl",
"SearchAll",
[{ query: query }])),
'Failed to retrieve entity data for query ' + query);
$http.get(
umbRequestHelper.getApiUrl(
"entityApiBaseUrl",
"SearchAll",
[{ query: query }]),
httpConfig),
'Failed to retrieve entity data for query ' + query);
}
};

View File

@@ -88,7 +88,7 @@ angular.module('umbraco.services')
throw "args.term is required";
}
return entityResource.search(args.term, "Document", args.searchFrom).then(function (data) {
return entityResource.search(args.term, "Document", args.searchFrom, args.canceler).then(function (data) {
_.each(data, function (item) {
configureContentResult(item);
});
@@ -138,7 +138,7 @@ angular.module('umbraco.services')
throw "args.term is required";
}
return entityResource.searchAll(args.term).then(function (data) {
return entityResource.searchAll(args.term, args.canceler).then(function (data) {
_.each(data, function(resultByType) {
switch(resultByType.type) {

View File

@@ -7,7 +7,7 @@
* Controls the search functionality in the site
*
*/
function SearchController($scope, searchService, $log, $location, navigationService) {
function SearchController($scope, searchService, $log, $location, navigationService, $q) {
$scope.searchTerm = null;
$scope.searchResults = [];
@@ -87,25 +87,41 @@ function SearchController($scope, searchService, $log, $location, navigationServ
$scope.selectedItem = group.results[itemIndex];
}
//watch the value change but don't do the search on every change - that's far too many queries
// we need to debounce
var debounced = _.debounce(function () {
if ($scope.searchTerm) {
$scope.isSearching = true;
navigationService.showSearch();
$scope.selectedItem = undefined;
searchService.searchAll({ term: $scope.searchTerm }).then(function (result) {
$scope.groups = _.filter(result, function(group){return group.results.length > 0;});
});
}else{
$scope.isSearching = false;
navigationService.hideSearch();
$scope.selectedItem = undefined;
}
}, 300);
//used to cancel any request in progress if another one needs to take it's place
var canceler = null;
$scope.$watch("searchTerm", debounced);
$scope.$watch("searchTerm", _.debounce(function (newVal, oldVal) {
$scope.$apply(function() {
if ($scope.searchTerm) {
if (newVal !== null && newVal !== undefined && newVal !== oldVal) {
$scope.isSearching = true;
navigationService.showSearch();
$scope.selectedItem = undefined;
//a canceler exists, so perform the cancelation operation and reset
if (canceler) {
console.log("CANCELED!");
canceler.resolve();
canceler = $q.defer();
}
else {
canceler = $q.defer();
}
searchService.searchAll({ term: $scope.searchTerm, canceler: canceler }).then(function(result) {
$scope.groups = _.filter(result, function (group) { return group.results.length > 0; });
//set back to null so it can be re-created
canceler = null;
});
}
}
else {
$scope.isSearching = false;
navigationService.hideSearch();
$scope.selectedItem = undefined;
}
});
}, 200));
}
//register it