我在我的应用程序中使用角度js。在ng-change事件中,我调用webservice并基于呈现html的响应。但是这里的ng-change调用过于频繁,我们快速键入,导致浏览器等待。这不是chrome和mozilla的问题。谁能在这帮助我?
答案 0 :(得分:6)
您可以使用超时并等待用户在拨打服务器之前完成输入:
<input type="text" ng-model="some.thing" ng-change="fetchData()" />
app.controller('someCtrl', function ($scope, $timeout) {
var fetchDataDelay = 500; // milliseconds
var fetchDataTimer;
$scope.fetchData = function () {
$timeout.cancel(fetchDataTimer);
fetchDataTimer = $timeout(function () {
// make expensive call to the server...
}, fetchDataDelay);
};
});
请注意,使用Angular的$timeout
(而非setTimeout/clearTimeout
)将为您处理Angular摘要周期(因此您无需亲自调用$apply()
或$digest()
)。
答案 1 :(得分:5)
我也遇到了类似的问题,我想实施一次去抖动搜索。经过一番重击之后,这就是我的所作所为:
这是我的输入字段,标有ng-model指令
<input ng-model="searchText" ng-model-options="{ debounce: 500 }" type="text" class="form-control" placeholder="Search...">
请注意我还包括了ng-model-options =&#34; {debounce:500}&#34;。它以指定的毫秒数去除底层模型的更新。 请参阅ng-model-options指令here的文档。
现在,我添加了一个这样的$ watch:
$scope.$watch('searchText', function(newValue) {
// expensive ajax call
});
请参阅$ watch here的文档。它注册一个事件监听器,监听作为第一个参数传递的表达式的任何变化。在这种情况下,&#39; searchText&#39;,这是与我的输入字段相关联的模型。
ng-model-options中提到的去抖动,对“搜索文本”的更新进行了辩护。模型,因此,它负责debouncing ajax调用(在我的情况下)。
希望它有所帮助。 :)
答案 2 :(得分:2)
你想要使用去抖模式,按照以下几行:
.factory('myFactory', function($http) {
var debounce;
var doRequest = function() {
clearTimeout(debounce);
setTimeout(function() {
// Make HTTP call here
}, 333);
};
return {
doRequest: doRequest
};
});
这样做是在最后一次调用之后发送请求333
毫秒。如果您在每次更改时都调用它,这将在请求之间添加一点间距,从而优化应用程序。
333
是Google用于文本输入的内容,您可以随意使用这些值并查看最适合您的内容。
答案 3 :(得分:2)
您可以使用$watch
或$watchCollection
来实现直播活动。
在我的理解和用法中,$ watch和$ watchCollection比ng-change安静有效。
这是一个很好的例子,
$scope.$watchCollection('[some_modelname,someother_modelname]',function(){
alert('Changed the input value!');
});
$scope.$watch('some_modelname',function(){
alert('Changed the input value!');
});
内部HTML,
<input type="text" ng-model="some_modelname" id="someid" name="somenameifneeded" value=""/>
<input type="text" ng-model="someother_modelname" id="someotherid" name="somenameifneeded" value=""/>
$watch
和$watchCollection
都会继续查看任何更改的输入字段。一旦进行任何更改,触发器将被调用,这将永远不会死。希望这会有所帮助。
答案 4 :(得分:1)
在angularjs 1/3上你有debounce作为ng-options这里是一个例子,所以你可以把它添加到你的ng-change,它会为你管理
ng-model-options="{debounce: {'default': 500} }
答案 5 :(得分:0)
你应该使用去抖方法 - 当你输入太频繁时,服务器不应该点击。当您停止键入并发生超时时,请求应发送到服务器。您可以使用Underscore Debounce feature或在此处进行自定义实施:
$scope.loadData = function () {
var loadThrottle;
clearTimeout(loadThrottle);
loadThrottle = setTimeout(function () {
$scope.$apply(function () {
$scope.getData();
});
}, 500);
};
此处的请求仅在您停止输入时发送,并且在此之后发生500ms超时。
另一种实施方式(使用愤怒的方法):
$scope.loadData = function(timeout) {
$scope.counter += 1;
var counter = $scope.counter;
$timeout(function(){
if (counter === $scope.counter) {
$scope.getData();
$scope.counter = 0;
}
}, timeout ? timeout : 500);
}
另外一种方法是使用更通用的方法使用自定义指令和Underscore之类的东西:
app.directive('changeTimeout', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ctrl) {
angular.forEach(ctrl.$viewChangeListeners, function(listener, index) {
ctrl.$viewChangeListeners[index] = _.debounce(function() {
scope.$apply(attrs.ngChange);
}, attrs.changeTimeout || 0)
});
}
}
});