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

Commit ae5eec4

Browse files
devversionThomasBurleson
authored andcommitted
fix(autocomplete): check select-on-match with cached results.
* The autocomplete was not checking for any exact matches if the results were cached. * Cached results will be now handled the same as they would be treated if they weren't cached. Fixes #8836. Closes #8853
1 parent 74b6298 commit ae5eec4

File tree

2 files changed

+74
-22
lines changed

2 files changed

+74
-22
lines changed

src/components/autocomplete/autocomplete.spec.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,7 @@ describe('<md-autocomplete>', function() {
11711171
});
11721172

11731173
describe('md-select-on-match', function() {
1174+
11741175
it('selects matching item on exact match when `md-select-on-match` is toggled', inject(function($timeout) {
11751176
var scope = createScope();
11761177
var template = '\
@@ -1196,6 +1197,44 @@ describe('<md-autocomplete>', function() {
11961197

11971198
element.remove();
11981199
}));
1200+
1201+
it('selects matching item on exact match with caching enabled', inject(function($timeout) {
1202+
var scope = createScope();
1203+
var template = '\
1204+
<md-autocomplete\
1205+
md-select-on-match\
1206+
md-selected-item="selectedItem"\
1207+
md-search-text="searchText"\
1208+
md-items="item in match(searchText)"\
1209+
md-item-text="item.display"\
1210+
placeholder="placeholder">\
1211+
<span md-highlight-text="searchText">{{item.display}}</span>\
1212+
</md-autocomplete>';
1213+
var element = compile(template, scope);
1214+
1215+
expect(scope.searchText).toBe('');
1216+
expect(scope.selectedItem).toBe(null);
1217+
1218+
scope.$apply('searchText = "foo"');
1219+
$timeout.flush();
1220+
1221+
expect(scope.selectedItem).not.toBe(null);
1222+
expect(scope.selectedItem.display).toBe('foo');
1223+
1224+
scope.$apply('searchText = ""');
1225+
$timeout.flush();
1226+
1227+
expect(scope.selectedItem).toBeFalsy();
1228+
1229+
scope.$apply('searchText = "foo"');
1230+
$timeout.flush();
1231+
1232+
expect(scope.selectedItem).not.toBe(null);
1233+
expect(scope.selectedItem.display).toBe('foo');
1234+
1235+
element.remove();
1236+
}));
1237+
11991238
it('should not select matching item on exact match when `md-select-on-match` is NOT toggled', inject(function($timeout) {
12001239
var scope = createScope();
12011240
var template = '\

src/components/autocomplete/js/autocompleteController.js

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
732732
isList = angular.isArray(items),
733733
isPromise = !!items.then; // Every promise should contain a `then` property
734734

735-
if (isList) handleResults(items);
735+
if (isList) onResultsRetrieved(items);
736736
else if (isPromise) handleAsyncResults(items);
737737

738738
function handleAsyncResults(items) {
@@ -744,7 +744,7 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
744744

745745
$mdUtil.nextTick(function () {
746746
items
747-
.then(handleResults)
747+
.then(onResultsRetrieved)
748748
.finally(function(){
749749
if (--fetchesInProgress === 0) {
750750
setLoading(false);
@@ -753,21 +753,16 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
753753
},true, $scope);
754754
}
755755

756-
function handleResults (matches) {
757-
cache[ term ] = matches;
758-
if ((searchText || '') !== ($scope.searchText || '')) return; //-- just cache the results if old request
756+
function onResultsRetrieved(matches) {
757+
cache[term] = matches;
759758

760-
ctrl.matches = matches;
761-
ctrl.hidden = shouldHide();
762-
763-
// If loading is in progress, then we'll end the progress. This is needed for example,
764-
// when the `clear` button was clicked, because there we always show the loading process, to prevent flashing.
765-
if (ctrl.loading) setLoading(false);
766-
767-
if ($scope.selectOnMatch) selectItemOnMatch();
759+
// Just cache the results if the request is now outdated.
760+
// The request becomes outdated, when the new searchText has changed during the result fetching.
761+
if ((searchText || '') !== ($scope.searchText || '')) {
762+
return;
763+
}
768764

769-
updateMessages();
770-
positionDropdown();
765+
handleResults(matches);
771766
}
772767
}
773768

@@ -833,20 +828,38 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
833828
* results first, then forwards the process to `fetchResults` if necessary.
834829
*/
835830
function handleQuery () {
836-
var searchText = $scope.searchText || '',
837-
term = searchText.toLowerCase();
838-
//-- if results are cached, pull in cached results
839-
if (!$scope.noCache && cache[ term ]) {
840-
ctrl.matches = cache[ term ];
841-
updateMessages();
842-
setLoading(false);
831+
var searchText = $scope.searchText || '';
832+
var term = searchText.toLowerCase();
833+
834+
// If caching is enabled and the current searchText is stored in the cache
835+
if (!$scope.noCache && cache[term]) {
836+
// The results should be handled as same as a normal un-cached request does.
837+
handleResults(cache[term]);
843838
} else {
844839
fetchResults(searchText);
845840
}
846841

847842
ctrl.hidden = shouldHide();
848843
}
849844

845+
/**
846+
* Handles the retrieved results by showing them in the autocompletes dropdown.
847+
* @param results Retrieved results
848+
*/
849+
function handleResults(results) {
850+
ctrl.matches = results;
851+
ctrl.hidden = shouldHide();
852+
853+
// If loading is in progress, then we'll end the progress. This is needed for example,
854+
// when the `clear` button was clicked, because there we always show the loading process, to prevent flashing.
855+
if (ctrl.loading) setLoading(false);
856+
857+
if ($scope.selectOnMatch) selectItemOnMatch();
858+
859+
updateMessages();
860+
positionDropdown();
861+
}
862+
850863
/**
851864
* If there is only one matching item and the search text matches its display value exactly,
852865
* automatically select that item. Note: This function is only called if the user uses the

0 commit comments

Comments
 (0)