Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Commit

Permalink
fix(autocomplete): stop loading if last promise got resolved
Browse files Browse the repository at this point in the history
> Just investigated a bit, the problem is, the autocomplete will set the loading state to false if a previous promise is resolved. So when you search for A-R-I-Z-O-N-A (normally typed - not pasted) there will be a promise for each char. So the state of setLoading will change to false. This can be solved by adding a simple fetching queue. But only check the queue on the promise finally to store the retrieved results in cache.

Fixes #6907

Closes #6927

# Conflicts:
#	src/components/autocomplete/js/autocompleteController.js
  • Loading branch information
devversion authored and ThomasBurleson committed Apr 1, 2016
1 parent 9e2eafa commit c718370
Showing 1 changed file with 34 additions and 16 deletions.
50 changes: 34 additions & 16 deletions src/components/autocomplete/js/autocompleteController.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
selectedItemWatchers = [],
hasFocus = false,
lastCount = 0,
promiseFetch = false;
fetchesInProgress = 0;

//-- public variables with handlers
defineProperty('hidden', handleHiddenChange, true);
Expand Down Expand Up @@ -164,8 +164,8 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
*/
function configureWatchers () {
var wait = parseInt($scope.delay, 10) || 0;
$attrs.$observe('disabled', function (value) { ctrl.isDisabled = !!value; });
$attrs.$observe('required', function (value) { ctrl.isRequired = !!value; });
$attrs.$observe('disabled', function (value) { ctrl.isDisabled = $mdUtil.parseAttributeBoolean(value, false); });
$attrs.$observe('required', function (value) { ctrl.isRequired = $mdUtil.parseAttributeBoolean(value, false); });
$scope.$watch('searchText', wait ? $mdUtil.debounce(handleSearchText, wait) : handleSearchText);
$scope.$watch('selectedItem', selectedItemChange);
angular.element($window).on('resize', positionDropdown);
Expand Down Expand Up @@ -638,21 +638,30 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
*/
function fetchResults (searchText) {
var items = $scope.$parent.$eval(itemExpr),
term = searchText.toLowerCase();
if (angular.isArray(items)) {
handleResults(items);
} else if (items) {
term = searchText.toLowerCase(),
isList = angular.isArray(items);

if ( isList ) handleResults(items);
else handleAsyncResults(items);

function handleAsyncResults(items) {
if ( !items ) return;

items = $q.when(items);
fetchesInProgress++;
setLoading(true);
promiseFetch = true;

$mdUtil.nextTick(function () {
if (items.success) items.success(handleResults);
if (items.then) items.then(handleResults);
if (items.finally) items.finally(function () {
setLoading(false);
promiseFetch = false;
});
items
.then(handleResults)
.finally(function(){
if (--fetchesInProgress === 0) {
setLoading(false);
}
});
},true, $scope);
}

function handleResults (matches) {
cache[ term ] = matches;
if ((searchText || '') !== ($scope.searchText || '')) return; //-- just cache the results if old request
Expand Down Expand Up @@ -707,14 +716,18 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
}
}

function isPromiseFetching() {
return fetchesInProgress !== 0;
}

function scrollTo (offset) {
elements.$.scrollContainer.controller('mdVirtualRepeatContainer').scrollTo(offset);
}

function notFoundVisible () {
var textLength = (ctrl.scope.searchText || '').length;

return ctrl.hasNotFound && !hasMatches() && (!ctrl.loading || promiseFetch) && textLength >= getMinLength() && (hasFocus || noBlur) && !hasSelection();
return ctrl.hasNotFound && !hasMatches() && (!ctrl.loading || isPromiseFetching()) && textLength >= getMinLength() && (hasFocus || noBlur) && !hasSelection();
}

/**
Expand Down Expand Up @@ -745,7 +758,12 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
matches = ctrl.matches,
item = matches[ 0 ];
if (matches.length === 1) getDisplayValue(item).then(function (displayValue) {
if (searchText == displayValue) select(0);
var isMatching = searchText == displayValue;
if ($scope.matchInsensitive && !isMatching) {
isMatching = searchText.toLowerCase() == displayValue.toLowerCase();
}

if (isMatching) select(0);
});
}

Expand Down

0 comments on commit c718370

Please sign in to comment.