我是新来AngularJS,和我有性能问题,我似乎无法应对。 我有瞬间的搜索,但它有点laggy,因为它开始在每个KEYUP搜索()。
JS:
var App = angular.module('App', []);
App.controller('DisplayController', function($scope, $http) {
$http.get('data.json').then(function(result){
$scope.entries = result.data;
});
});
HTML:
<input id="searchText" type="search" placeholder="live search..." ng-model="searchText" />
<div class="entry" ng-repeat="entry in entries | filter:searchText">
<span>{{entry.content}}</span>
</div>
JSON数据甚至不是很大,只有300KB,我想我需要做到的是把对搜索〜1秒的延迟,以等待用户来完成的,而不是执行上的每个按键动作打字。 AngularJS做到这一点内部,以及阅读文档在这里和其他主题后,我无法找到一个明确的答案。
我很感激我如何能延缓即时搜索任何指针。 谢谢。
Answer 1:
(请参阅下面回答一个角1.3解决方案。)
这里的问题是,搜索将执行每一个模型发生变化时,这是对输入的每个KEYUP行动。
将会有简洁的方式来做到这一点,但可能是最简单的方法是将切换的结合,使该款你的过滤器操作的控制器内定义的范围$属性。 这样,你可以控制$ scope变量是如何经常更新。 事情是这样的:
JS:
var App = angular.module('App', []);
App.controller('DisplayController', function($scope, $http, $timeout) {
$http.get('data.json').then(function(result){
$scope.entries = result.data;
});
// This is what you will bind the filter to
$scope.filterText = '';
// Instantiate these variables outside the watch
var tempFilterText = '',
filterTextTimeout;
$scope.$watch('searchText', function (val) {
if (filterTextTimeout) $timeout.cancel(filterTextTimeout);
tempFilterText = val;
filterTextTimeout = $timeout(function() {
$scope.filterText = tempFilterText;
}, 250); // delay 250 ms
})
});
HTML:
<input id="searchText" type="search" placeholder="live search..." ng-model="searchText" />
<div class="entry" ng-repeat="entry in entries | filter:filterText">
<span>{{entry.content}}</span>
</div>
Answer 2:
UPDATE
现在,比以往任何时候(角1.3)比较容易,只需添加模型上的去抖动选项。
<input type="text" ng-model="searchStr" ng-model-options="{debounce: 1000}">
更新plunker:
http://plnkr.co/edit/4V13gK
文档上ngModelOptions:
https://docs.angularjs.org/api/ng/directive/ngModelOptions
老方法:
下面是与超越的角度本身没有依赖关系的另一种方法。
您需要设置超时时间,并且当前字符串与过去的版本进行比较,如果两者是相同的,然后它的搜索。
$scope.$watch('searchStr', function (tmpStr)
{
if (!tmpStr || tmpStr.length == 0)
return 0;
$timeout(function() {
// if searchStr is still the same..
// go ahead and retrieve the data
if (tmpStr === $scope.searchStr)
{
$http.get('//echo.jsontest.com/res/'+ tmpStr).success(function(data) {
// update the textarea
$scope.responseData = data.res;
});
}
}, 1000);
});
这对进入自己的看法:
<input type="text" data-ng-model="searchStr">
<textarea> {{responseData}} </textarea>
强制性plunker: http://plnkr.co/dAPmwf
Answer 3:
在角1.3我这样做:
HTML:
<input ng-model="msg" ng-model-options="{debounce: 1000}">
控制器:
$scope.$watch('variableName', function(nVal, oVal) {
if (nVal !== oVal) {
myDebouncedFunction();
}
});
基本上你告诉角运行myDebouncedFunction(),味精范围变量发生变化的时候。 属性NG-模型选项=“{反跳:1000}”确保味精只能更新一次第二。
Answer 4:
<input type="text"
ng-model ="criteria.searchtext""
ng-model-options="{debounce: {'default': 1000, 'blur': 0}}"
class="form-control"
placeholder="Search" >
现在,我们可以设置NG-模型选项去抖随着时间的推移,当模糊,模型需要否则就立即改变保存它有旧值,如果没有完成延迟。
Answer 5:
对于那些谁在HTML标记使用KEYUP / KEYDOWN。 这不使用手表。
JS
app.controller('SearchCtrl', function ($scope, $http, $timeout) {
var promise = '';
$scope.search = function() {
if(promise){
$timeout.cancel(promise);
}
promise = $timeout(function() {
//ajax call goes here..
},2000);
};
});
HTML
<input type="search" autocomplete="off" ng-model="keywords" ng-keyup="search()" placeholder="Search...">
Answer 6:
去抖/节流的angularjs模型更新: http://jsfiddle.net/lgersman/vPsGb/3/
在你的情况下,有什么比在这样的的jsfiddle代码中使用指示去做:
<input
id="searchText"
type="search"
placeholder="live search..."
ng-model="searchText"
ng-ampere-debounce
/>
其基本上是一个小块代码由命名为“NG-安培防反跳”利用单个的角指令的http://benalman.com/projects/jquery-throttle-debounce-plugin/其可以附连到任何DOM元素。 该指令重新排序的附加事件处理程序,以便它可以控制何时节流阀事件。
你可以用它来节流/去抖*模型的角度更新*角事件处理NG- [事件] * jQuery的事件处理程序
看一看: http://jsfiddle.net/lgersman/vPsGb/3/
该指令将是Orangevolt安培框架(的一部分https://github.com/lgersman/jquery.orangevolt-ampere )。
Answer 7:
只是为用户重定向这里:
正如在介绍Angular 1.3
可以使用NG-模型选项属性:
<input
id="searchText"
type="search"
placeholder="live search..."
ng-model="searchText"
ng-model-options="{ debounce: 250 }"
/>
Answer 8:
我认为,解决这个问题的最好方法是使用本Alman的插件jQuery的油门/反跳 。 在我看来,没有必要推迟表单每一个领域的事件。
只是包装你的$ $范围观看$ .debounce这样的处理功能:
$scope.$watch("searchText", $.debounce(1000, function() {
console.log($scope.searchText);
}), true);
Answer 9:
另一种方法是延迟功能添加到模型更新。 简单的指令似乎做了一招:
app.directive('delayedModel', function() {
return {
scope: {
model: '=delayedModel'
},
link: function(scope, element, attrs) {
element.val(scope.model);
scope.$watch('model', function(newVal, oldVal) {
if (newVal !== oldVal) {
element.val(scope.model);
}
});
var timeout;
element.on('keyup paste search', function() {
clearTimeout(timeout);
timeout = setTimeout(function() {
scope.model = element[0].value;
element.val(scope.model);
scope.$apply();
}, attrs.delay || 500);
});
}
};
});
用法:
<input delayed-model="searchText" data-delay="500" id="searchText" type="search" placeholder="live search..." />
所以,你只需要使用delayed-model
代替ng-model
和定义所需的data-delay
。
演示: http://plnkr.co/edit/OmB4C3jtUD2Wjq5kzTSU?p=preview
Answer 10:
我解决了这个问题与basicly它的作用是在一个特殊的属性,真正的NG-模型,我看在指令绑定,然后使用去抖服务更新我的指令属性的指令,所以对变量的用户手表他结合抖模型代替NG-模型。
.directive('debounceDelay', function ($compile, $debounce) {
return {
replace: false,
scope: {
debounceModel: '='
},
link: function (scope, element, attr) {
var delay= attr.debounceDelay;
var applyFunc = function () {
scope.debounceModel = scope.model;
}
scope.model = scope.debounceModel;
scope.$watch('model', function(){
$debounce(applyFunc, delay);
});
attr.$set('ngModel', 'model');
element.removeAttr('debounce-delay'); // so the next $compile won't run it again!
$compile(element)(scope);
}
};
});
用法:
<input type="text" debounce-delay="1000" debounce-model="search"></input>
而在控制器:
$scope.search = "";
$scope.$watch('search', function (newVal, oldVal) {
if(newVal === oldVal){
return;
}else{ //do something meaningful }
演示中的jsfiddle: http://jsfiddle.net/6K7Kd/37/
在$防抖动服务可以在这里找到: http://jsfiddle.net/Warspawn/6K7Kd/
通过eventuallyBind指令启发 http://jsfiddle.net/fctZH/12/
Answer 11:
角1.3将有NG-模型选项去抖,但在那之前,你必须使用一个计时器像若苏埃伊瓦拉说。 然而,在他的代码,他推出的每一个按键的计时器。 此外,他使用的setTimeout,当角一个必须使用$超时或使用$适用于setTimeout的结束。
Answer 12:
为什么大家都希望利用手表吗? 你也可以使用一个函数:
var tempArticleSearchTerm;
$scope.lookupArticle = function (val) {
tempArticleSearchTerm = val;
$timeout(function () {
if (val == tempArticleSearchTerm) {
//function you want to execute after 250ms, if the value as changed
}
}, 250);
};
Answer 13:
我觉得这里最简单的方法是预加载JSON或上一次加载$dirty
,然后过滤搜索将照顾休息。 这会为你节省额外的HTTP调用,并与预加载的数据要快得多。 记忆会受到伤害,但它是值得的。
文章来源: How to put a delay on AngularJS instant search?