限制预输入结果结果

2023-09-13 04:03:09 作者:公主殿下

我用角UI预输入指令连接到谷歌地图API和检索地址的数组。通常,当我需要限制结果的数量可见我做这样的事情:

 <输入预输入=眼睛在阵列眼|过滤器:$ viewValue | limitTo:10> 

这完美的作品,结果被限制为10。然而,当我尝试做异步结果同样的事情,这是行不通的。比我在 limitTo 指定它将给更多的结果。

我做下面的不正确的东西?

这里是一个plunker:

HTML

 <输入NG模型=asyncSelected预输入=地址中的getLocation($ viewValue)地址| limitTo:1预输入加载=loadingLocations> 
Excel怎样限制输入数据范围,限制输入数据大小

JavaScript的:

  $ scope.getLocation =功能(VAL){    返回$ http.get('http://maps.googleapis.com/maps/api/geo$c$c/json',{      params:一个{        地址:VAL      }    }),然后(功能(RES){      变种地址= [];      angular.forEach(res.data.results,函数(项目){        addresses.push(item.formatted_address);      });      返回地址;    });  }; 

目前我做下面要解决,我只是好奇,为什么一个简单的 limitTo 不起作用。

  $ scope.getLocation =功能(VAL){    返回$ http.get('http://maps.googleapis.com/maps/api/geo$c$c/json',{      params:一个{        地址:VAL      }    }),然后(功能(RES){      变种地址= [];      VAR resultNumber = res.data.results.length> 5? 5:res.data.results.length;      对于(VAR I = 0; I< resultNumber;我++){        VAR OBJ = res.data.results [I]        VAR地址= obj.formatted_address;        addresses.push(地址);      }            返回地址;    });  }; 

解决方案

键盘缓冲似乎并不支持承诺。因此,最好只将其绑定到一个集合,然后更新集合时,你从谷歌的回应。您可能要考虑一下去抖艰难,现在请求一个输入每个字母完成。

请注意,您也不必过滤了,因为过滤器已经被谷歌做断绝身边。

http://plnkr.co/edit/agwEDjZvbq7ixS8El3mu?p=$p$ PVIEW

  VAR应用= angular.module('应用',['ui.bootstrap']);app.controller(按Ctrl',['$范围,$ HTTP',函数($范围,$ HTTP){  $ scope.locations = [];  $范围。$腕表('asyncSelected',函数(VAL){    $ http.get('http://maps.googleapis.com/maps/api/geo$c$c/json',{      params:一个{        地址:VAL      }    }),然后(功能(RES){      $ scope.locations.length = 0;      angular.forEach(res.data.results,函数(项目){        $ scope.locations.push(item.formatted_address);      });    });  });}]); 

 &LT; HEAD&GT;    &LT;链路数据需要=bootstrap-css@~3.1.1数据semver =3.2.0的rel =stylesheet属性HREF =// maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/ bootstrap.min.css/&GT;    &所述;脚本数据需要=angular.js@*数据semver =1.3.0-beta.5SRC =HTTPS://$c$c.angularjs.org/1.3.0-beta.5 /angular.js\"></script>    &LT;脚本数据需要=UI自举@ *数据semver =0.11.0SRC =htt​​p://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0。 min.js&GT;&LT; / SCRIPT&GT;    &所述;脚本数据需要=的jquery @ *数据semver =2.1.1SRC =// cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js\"> &LT; / SCRIPT&GT;    &LT;脚本数据需要=引导@ *数据semver =3.1.1SRC =// netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js\">< / SCRIPT&GT;    &LT;链接rel =stylesheet属性HREF =style.css文件/&GT;    &所述; SCRIPT SRC =的script.js&GT;&下; /脚本&GT;  &LT; /头&GT;  &LT;机身NG-应用=应用程序NG控制器=CTRL&GT;    &LT;输入类型=文本NG模型=asyncSelected占位符=地址预输入=地址中的位置地址| limitTo:1预输入加载=loadingLocations级=表格控&GT;  &LT; /身体GT;&LT; / HTML&GT; 

I'm using the angular-ui typeahead directive to connect to the Google Maps API and retrieve an array of addresses. Normally when I need to limit the amount of results visible I do something like:

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

That works perfectly and the results are limited to 10. However, when I try to do the same thing with asynchronous results, it doesn't work. It will give more results than I specified in the limitTo.

Am I doing something incorrectly below?

Here is a 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;
    });
  };

Currently i'm doing the following to workaround, i'm just curious why a simple limitTo doesn't work.

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

解决方案

typeahead doesn't seem to support promises. So it's better to just bind it to a collection, and then update that collection when you get a response from google. You might want to think about debouncing tough, now a request is done for every letter typed.

Note that you also don't need the filter anymore, because the filter is already being done by google sever side.

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>