简体   繁体   中英

Angular Material Autocomplete - Searches on Select

I've created this cool little control in Angular Material that anyone is welcome to use (see fiddle). It's basically an Angular Material's Autocomplete field that utilizes Google's Geolocation service as you type. Since doesn't have a delay directive, I'm adding special code to only search when the user stops typing after 700ms.

My problem is - why does the MD-Autocomplete fire a query event as soon as an item is selected?

Here is HTML:

<md-autocomplete flex style="width: 50%; margin: auto; padding-top: 10em" 
    md-no-cache="false"
    md-selected-item="ctrl.orig_loc"
    md-search-text="ctrl.orig_loc_query"
    md-items="item in querySearch(ctrl.orig_loc_query)"
    md-selected-item-change="selectedItem(ctrl.orig_loc)"
    md-item-text="ctrl.orig_loc.formatted_address"
    md-floating-label="Type address or location name">

    <span md-highlight-text="">{{item.formatted_address}}</span>
</md-autocomplete>

Here is JS querySearch function:

// this is called every time a user types a character AND when item is selected... for some odd reason
$scope.querySearch = function(query) {
    var deferred = $.Deferred();

    // clear old request if something typed within 700ms
    if (locQuery) {
        clearTimeout(locQuery);
    }
    // run the query in 700ms. it will be cleared if the user types within 700ms
    locQuery = setTimeout(function() {
        // call google's geocoder
        geocoder.geocode({
            'address': query
        }, deferred.resolve);
    }, 700);

    return deferred.promise().then(function(response) {
        return response;
    });
};

Here is the fiddle: https://jsfiddle.net/NeoSHNIK/jgpgv4Ls/3/

Again, the problem is - after you make a selection, it will do another search... why?

I kinda figured it out. Its happening because the field's variable "searchText" changes two times before it gets formatted by my formatter "{{item.formatted_address}}". This field is being watched by a $scope.$watch in angular-material library. So every time it changes - they call handleSearchText() which does the search. So instead they should really add a "delay" concept that would fix my problem as well as fix the problem of a remote search (don't want to search every character a user types). It would be nice to add a delay to the autocomplete control. But for now I'm just modified angular-material library and it gets the work done:

  function configureWatchers () {
    var wait = 700; //MY HACK
    $attrs.$observe('disabled', function (value) { ctrl.isDisabled = $mdUtil.parseAttributeBoolean(value, false); });
    $attrs.$observe('required', function (value) { ctrl.isRequired = $mdUtil.parseAttributeBoolean(value, false); });
    $attrs.$observe('readonly', function (value) { ctrl.isReadonly = $mdUtil.parseAttributeBoolean(value, false); });
    $scope.$watch('searchText', wait ? $mdUtil.debounce(handleSearchText, wait) : handleSearchText);
    $scope.$watch('selectedItem', selectedItemChange);
    angular.element($window).on('resize', positionDropdown);
    $scope.$on('$destroy', cleanup);
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM