【问题标题】:Angularjs autocomplete very slowAngularjs自动完成非常慢
【发布时间】:2015-05-19 15:50:00
【问题描述】:

我在 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 秒或更长时间内显示结果!!有没有办法让它更快?实际上,每次我在输入中输入某些内容时,都会启动一个请求,如果之后立即有另一个请求则中止。如果可能的话,我需要做这种方法或类似但更快的方法

【问题讨论】:

    标签: javascript jquery angularjs autocomplete angular-promise


    【解决方案1】:

    您可以使用ng-model-options={debounce:500} link to ng-model-option documentation(使用此选项,您会在 500 毫秒后更新模型,如果在此期间您进行了其他更改,则不会更新它)[旧]并调用 ng-change 您的函数以显示自动完成结果。[/old] [编辑] 并调用一个观察者你的函数来显示自动完成的结果。 [/edited]

    如果我必须做类似的事情,也许我会使用 debounce 500,在函数中我会检查我是否已经有一个数据集合,以及新的输入模型是否是之前的一个子集,在这种情况下,我将只过滤我已经拥有的结果集没有重做 http 调用,否则我会重做调用。

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

    我觉得这个cos离完美还很远,但是这个想法是我试图解释的。

    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>

    【讨论】:

    • mmh.. 你能告诉我带有 ng-change 的 javascript 部分是什么意思吗?
    猜你喜欢
    • 2011-01-11
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 2013-06-16
    • 2014-07-04
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    相关资源
    最近更新 更多