Angularjs自动完成非常慢

时间:2015-05-18 13:24:05

标签: javascript jquery angularjs autocomplete angular-promise

我使用angularjs中的超时创建了一个自动完成输入。它工作但很慢。这是代码:

var promiseCanceller = $q.defer();
        $scope.updateSearchResultsNew = function (textTyped) {
            if ($scope.searchTxt.length >= 2) {
                promiseCanceller.resolve("cancelled");
                promiseCanceller = $q.defer();
                $scope.loading = true;
                $http.get($scope.baseUrl + uri, {
                        params: {
                            text: encodeURIComponent(textTyped)+("*"),
                            filters: $scope.filter
                        },
                        timeout: promiseCanceller.promise
                    })
                    .success(function (data) {
                        $scope.searchResults = data.data;
                        $scope.loading = false;

                    });
            } else {
                $scope.searchResults = [];
                $scope.loading = true;

            }
        };

有时它会在大约19秒或更长时间内显示结果!有没有办法让它更快?实际上,每当我在输入中输入内容时,如果在此之后立即有另一个请求,则会启动请求。我需要做这种方法或类似的东西,但如果可能的话更快

1 个答案:

答案 0 :(得分:2)

您可以使用ng-model-options={debounce:500} auto-Implemented property(使用此选项可以在500毫秒后更新模型,如果在那段时间内进行了其他更改,则不会更新模型) [old] 并致电ng-change您的函数以显示自动填充结果。 [/ old] [编辑] 并在监视器中调用您的函数来显示自动完成的结果。 的 [/编辑]

如果我必须做那样的事情,也许我会使用debounce 500,在函数中我会检查我是否已经有数据集合,如果新的输入模型是之前的子集,那么我只会过滤结果集我已经没有重做http呼叫,否则我会重做呼叫。

编辑: 对不起,我已经用观察者做了,因为我还需要检查输入的先前值。

我认为这种情况远非完美,但我的想法是我试图解释。

angular.module('autocompleteTest', [])
  .controller('testCtrl', ['$scope', 'simulateHttpCall', '$q',
    function($scope, simulateHttpCall, $q) {
      var promiseCheck;
      $scope.results = null;

      $scope.$watch('search', function(newVal, oldVal) {
        if (newVal != oldVal) {
          if (!newVal && newVal.length === 0) {
            $scope.results = null;
          } else {
            if (!$scope.results  || oldVal.indexOf(newVal) !== -1 || oldVal.length > newVal.length ) {
              promiseCheck = simulateHttpCall.get(newVal).then(
                function(res) {
                  $scope.results = res;
                },
                function(err) {
                  $scope.results =['Error!'];
                }
              );
            } else {
              $q.when(promiseCheck).then(
                function(res){
                  $scope.results = $scope.results.filter(function(el) {
                    return (el.indexOf(newVal) !== -1);
                  });
                },
                function(err){
                  $scope.results = ['Error!'];
                }
              );
            }                        
          }
        }        
      });
    }
  ])
  .factory('simulateHttpCall', ['$timeout', '$q',
    function($timeout, $q) {
      var rt = {};

      rt.get = _getResults;


      function _getResults(string) {
        var deferred = new $q.defer();

        var set = ["Lorem", "ipsum", "dolor", "sit", "amet,", "consectetur", "adipiscing", "elit,", "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", "magna", "aliqua.", "Ut", "enim", "ad", "minim", "veniam,", "quis", "nostrud", "exercitation", "ullamco", "laboris", "nisi", "ut", "aliquip", "ex", "ea", "commodo", "consequat.", "Duis", "aute", "irure", "dolor", "in", "reprehenderit", "in", "voluptate", "velit", "esse", "cillum", "dolore", "eu", "fugiat", "nulla", "pariatur.", "Excepteur", "sint", "occaecat", "cupidatat", "non", "proident,", "sunt", "in", "culpa", "qui", "officia", "deserunt", "mollit", "anim", "id", "est", "laborum."];


      
        
        $timeout(function() {
          var filteredSet = set.filter(function(el) {
            return el.match(string);
          });
          deferred.resolve(filteredSet);
          
        }, 2000);

        return deferred.promise;
      }

      return rt;
    }
  ]);
.results {
  margin-top: 10px;
  border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="autocompleteTest" ng-controller="testCtrl" class="app">


  <input ng-model="search" ng-model-options="{debouce:500}" placeholder="search" />

  <ul class="results" ng-model="results">

    <li ng-hide="results.length != 0">No result</li>
     
    <li ng-repeat="res in results track by $index">{{res}}</li>
  </ul>


</div>