0

Ich habe dieses coole kleine Steuerelement in Angular Material, das jeder gerne verwenden kann (siehe Geige) erstellt. Es handelt sich im Grunde um das Autocomplete-Feld eines Angular-Materials, das während der Eingabe den Geolocation-Dienst von Google verwendet. Da es keine Verzögerungs-Direktive gibt, füge ich speziellen Code hinzu, um nur zu suchen, wenn der Benutzer nach 700ms aufhört zu tippen.Angular Material Autocomplete - Suche auf Wählen

Mein Problem ist - warum feuert die MD-Autocomplete ein Abfrageereignis, sobald ein Element ausgewählt ist?

Hier 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> 

Hier JS querySearch Funktion:

// 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; 
    }); 
}; 

Hier ist die Geige: https://jsfiddle.net/NeoSHNIK/jgpgv4Ls/3/

Auch hier ist das Problem - nachdem Sie eine Auswahl treffen , es wird eine andere Suche machen ... warum?

Antwort

0

Ich habe es irgendwie herausgefunden. Es passiert, weil die Feldvariable "searchText" sich zweimal ändert, bevor sie von meinem Formatierer "{{item.formated_address}}" formatiert wird. Dieses Feld wird von einem $ scope. $ Watch in der eckigen Materialbibliothek überwacht. Jedes Mal, wenn es sich ändert, rufen sie handleSearchText() auf, was die Suche ausführt. Stattdessen sollten sie wirklich ein "Verzögerungs" -Konzept hinzufügen, das mein Problem behebt und das Problem einer Remote-Suche behebt (ich möchte nicht jedes Zeichen, das ein Benutzer tippt, durchsuchen). Es wäre nett, dem Autocomplete-Steuerelement eine Verzögerung hinzuzufügen. Aber für jetzt bin ich nur modifizierte Winkel-Material-Bibliothek und es wird die Arbeit getan:

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); 
    }