Question

J'utilise la directive angulaire-ui typeahead pour me connecter à l'API Google Maps et récupérer un tableau d'adresses.Normalement, lorsque je dois limiter la quantité de résultats visibles, je fais quelque chose comme :

<input typeahead="eye for eye in array | filter:$viewValue | limitTo:10">

Cela fonctionne parfaitement et les résultats sont limités à 10.Cependant, lorsque j’essaie de faire la même chose avec des résultats asynchrones, cela ne fonctionne pas.Cela donnera plus de résultats que ce que j'ai spécifié dans le limitTo.

Est-ce que je fais quelque chose de mal ci-dessous ?

Voici un plunker :

HTML :

  <input ng-model="asyncSelected" typeahead="address for address in getLocation($viewValue) | limitTo:1" typeahead-loading="loadingLocations">

Javascript :

  $scope.getLocation = function(val) {
    return $http.get('http://maps.googleapis.com/maps/api/geocode/json', {
      params: {
        address: val
      }
    }).then(function(res){
      var addresses = [];
      angular.forEach(res.data.results, function(item){
        addresses.push(item.formatted_address);
      });
      return addresses;
    });
  };

Actuellement, je fais ce qui suit pour contourner le problème, je suis juste curieux de savoir pourquoi un simple limitTo ça ne marche pas.

$scope.getLocation = function(val) {
    return $http.get('http://maps.googleapis.com/maps/api/geocode/json', {
      params: {
        address: val
      }
    }).then(function(res){
      var addresses = [];
      var resultNumber = res.data.results.length > 5 ? 5 : res.data.results.length;
      for(var i = 0; i < resultNumber; i++){
        var obj = res.data.results[i];
        var addr = obj.formatted_address;
        addresses.push(addr);
      }
            return addresses;
    });
  };
Était-ce utile?

La solution

la saisie anticipée ne semble pas prendre en charge les promesses.Il est donc préférable de simplement le lier à une collection, puis de mettre à jour cette collection lorsque vous recevez une réponse de Google.Vous voudrez peut-être penser à anti-rebondir, maintenant une demande est effectuée pour chaque lettre tapée.

Notez que vous n'avez plus besoin du filtre, car le filtre est déjà effectué par Google Server.

http://plnkr.co/edit/agwEDjZvbq7ixS8El3mu?p=preview

var app = angular.module('app',['ui.bootstrap']);

app.controller('Ctrl', ['$scope','$http', function($scope,$http){
  $scope.locations = [];
  $scope.$watch('asyncSelected', function(val) {
    $http.get('http://maps.googleapis.com/maps/api/geocode/json', {
      params: {
        address: val
      }
    }).then(function(res){
      $scope.locations.length = 0;
      angular.forEach(res.data.results, function(item){
        $scope.locations.push(item.formatted_address);
      });
    });
  });

}]);

  <head>
    <link data-require="bootstrap-css@~3.1.1" data-semver="3.2.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
    <script data-require="angular.js@*" data-semver="1.3.0-beta.5" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
    <script data-require="ui-bootstrap@*" data-semver="0.11.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.min.js"></script>
    <script data-require="jquery@*" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script data-require="bootstrap@*" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-app="app" ng-controller="Ctrl">
    <input type="text" ng-model="asyncSelected" placeholder="Address" typeahead="address for address in locations | limitTo:1" typeahead-loading="loadingLocations" class="form-control">
  </body>

</html>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top