使用自定义搜索过滤器
HTML
<input type="text" pInputText class="ui-widget ui-text" [(ngModel)]
="gloablFilterValue" (ngModelChange)="splitCustomFilter()" placeholder="Find" />
我在搜索框
上使用ngModelChange()
个事件
globalSearch(realData, searchText, columns) {
searchText = searchText.toLowerCase();
return realData.filter(function (o) {
return columns.some(function (k) {
return o[k].toString().toLowerCase().indexOf(searchText) !== -1;
});
});
}
splitCustomFilter() {
let columns =
['PartNoCompleteWheel', 'DescriptionCompleteWheel', 'PartNoTyre', 'DescriptionTyre', 'PartNoRim', 'DescriptionRim','DeletedDateFromKDPStr', 'DateFromKDPStr', 'Status'];
this.tyreAndRimList = this.globalSearch(this.tyreAndRimList, this.gloablFilterValue, columns);
}
&#13;
this.tyreAndRimList
变量中提到的列的column
值列表。
问题
过滤器工作正常!但主要问题是过滤器性能非常差,而记录数量很大(每列超过100行)
:当
如果输入单个字符(例如a
),则过滤器工作正常。但是当我不断地输入字符时,浏览器就会挂起。原因是过滤器已经过滤了过滤器盒上的每一个类型(因为我正在使用ngModelChange()// onchange()
事件)
我想要什么
如果用户在搜索框上连续输入,我想停止过滤。一旦用户停止输入,那么我只需要开始过滤。
我做了什么
我尝试使用setTimeout()
处理此问题。但它只是等待过滤器调用一秒钟。如果用户连续输入2或3个字符,它就可以正常工作。但是如果用户键入超过7或8或更高的字符,它将继续挂起浏览器。因为许多过滤器回调都在同一时间进行处理。
setTimeout(() => //code of filtering ,1000);
问题
如何在用户连续输入值时停止过滤,并在用户停止输入后开始过滤?
我在angular-2和打字稿中工作。但是这个问题与angularjs
或angular
或JavaScript
或typescript
无关,因为我想要一个想法而不是解决方案。所以我会为这个问题添加所有标签。不要删除它。感谢
答案 0 :(得分:2)
去抖动功能。看看下划线是如何做到的:Function Debouncing with Underscore.js。
然后你会生成你的函数的去抖版本:
var globalSearchDebounced = _.debounce(globalSearch, 100, false);
只有在用户停止输入至少一秒后才会调用。
答案 1 :(得分:1)
无法中断Array.filter
方法。根据你的需要,你可以这样处理:
let timerId = null
function handleChange() {
if(timerId) {
clearTimeout(timerId)
}
timerId = setTimeout(() => /* Array.filter(...) */, 1000)
}
<强>解释强>
拥有一个包含timerId
函数返回的setTimeout
的变量。每次模型更改时,都会调用handleChange
函数(在本例中)。该函数检查包含timerId
的变量是否已设置且包含timerId
,当变量包含timerId
时,将调用clearTimeout
函数以清除先前的超时之后,handleChange创建一个新的超时,并将timerId
(从setTimeout
函数返回)分配给变量。
setTimeout
clearTimeout
答案 2 :(得分:1)
如果没有下划线,并且没有Timeout(顺便触发整个Angular生命周期),您可以使用具有异步管道和去抖动的Observable。
在您的全球搜索功能中:
return Observable.of(/* filter here and return the filtered array */).debounceTime(1000)
在你的清单中(我猜想必须在某处)
<list-item *ngFor="let x of myFilteredResults | async">...</list-item>
答案 3 :(得分:0)
我已使用Subject
到debounceTime
完成了该操作。
private subject = new Subject<string>()
ngOnInit() {
this.subject.debounceTime(300).subscribe(inputText => {
this.gloablFilterValue = inputText;
this.splitCustomFilter(); // filter method
});
}
现在,当我使用change事件更改this.gloablFilterValue
对象中的值时。它只是等待事件结束。