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