如何停止 array.filter() 函数
how to stop array.filter() function
我正在使用自定义搜索过滤器
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);
}
column
变量中提到的列的 this.tyreAndRimList
值列表。
问题
过滤器运行良好!但主要问题是过滤性能很差,而记录数很大(每列超过 100 行)
当
如果输入单个字符(如 a
),过滤器工作正常。但是当我连续输入字符时,浏览器挂起。原因是过滤器一直在触发过滤器框中的每个输入(因为我正在使用 ngModelChange()// onchange()
事件)
我想要的
如果用户在搜索框中连续键入,我想停止过滤。一旦用户停止输入,那么只有我需要开始过滤。
我做了什么
我尝试使用 setTimeout()
来处理这个问题。但它只是等待过滤器调用一秒钟。如果用户连续输入 2 或 3 个字符,它就会起作用。但如果用户键入超过 7 个或 8 个或以上的字符,它会继续挂起浏览器。因为许多过滤器回调正在同时处理。
setTimeout(() => //code of filtering ,1000);
问题
如何在用户连续输入值时停止过滤并在用户停止输入后开始过滤?
我正在使用 angular-2 和打字稿。但是这个问题只与 angularjs
或 angular
或 JavaScript
或 typescript
无关,因为我想要的是想法而不是解决方案。所以我会为这个问题添加所有标签。不要删除它。谢谢
去抖函数。在这里查看下划线是如何做到的:Function Debouncing with Underscore.js。
然后您将生成函数的去抖动版本,如下所示:
var globalSearchDebounced = _.debounce(globalSearch, 100, false);
它只会在用户停止输入至少一秒钟后调用。
无法中断Array.filter
方法。根据您的需要,您可以这样处理:
let timerId = null
function handleChange() {
if(timerId) {
clearTimeout(timerId)
}
timerId = setTimeout(() => /* Array.filter(...) */, 1000)
}
说明
有一个变量,它将包含从 setTimeout
函数返回的 timerId
。每次更改模型时,都会调用 handleChange
函数(在本例中)。该函数检查包含timerId
的变量是否被设置并包含一个timerId
,当变量包含timerId
时将调用clearTimeout
函数来清除之前的超时之后 handleChange 创建一个新的超时并将 timerId
(从 setTimeout
函数返回)分配给变量。
setTimeout
的文档
clearTimeout
的文档
没有下划线,也没有超时(顺便说一句,这将触发整个 Angular 生命周期),您可以使用带有异步管道和去抖动的 Observable。
在您的全局搜索功能中:
return Observable.of(/* filter here and return the filtered array */).debounceTime(1000)
在你的列表中(我猜这一定是某个地方)
<list-item *ngFor="let x of myFilteredResults | async">...</list-item>
我已经用Subject
到debounceTime
完成了。
private subject = new Subject<string>()
ngOnInit() {
this.subject.debounceTime(300).subscribe(inputText => {
this.gloablFilterValue = inputText;
this.splitCustomFilter(); // filter method
});
}
现在,当我使用更改事件更改 this.gloablFilterValue
对象中的值时。它只是等待事件完成结束。
我正在使用自定义搜索过滤器
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);
}
column
变量中提到的列的 this.tyreAndRimList
值列表。
问题
过滤器运行良好!但主要问题是过滤性能很差,而记录数很大(每列超过 100 行)
当
如果输入单个字符(如 a
),过滤器工作正常。但是当我连续输入字符时,浏览器挂起。原因是过滤器一直在触发过滤器框中的每个输入(因为我正在使用 ngModelChange()// onchange()
事件)
我想要的
如果用户在搜索框中连续键入,我想停止过滤。一旦用户停止输入,那么只有我需要开始过滤。
我做了什么
我尝试使用 setTimeout()
来处理这个问题。但它只是等待过滤器调用一秒钟。如果用户连续输入 2 或 3 个字符,它就会起作用。但如果用户键入超过 7 个或 8 个或以上的字符,它会继续挂起浏览器。因为许多过滤器回调正在同时处理。
setTimeout(() => //code of filtering ,1000);
问题
如何在用户连续输入值时停止过滤并在用户停止输入后开始过滤?
我正在使用 angular-2 和打字稿。但是这个问题只与 angularjs
或 angular
或 JavaScript
或 typescript
无关,因为我想要的是想法而不是解决方案。所以我会为这个问题添加所有标签。不要删除它。谢谢
去抖函数。在这里查看下划线是如何做到的:Function Debouncing with Underscore.js。
然后您将生成函数的去抖动版本,如下所示:
var globalSearchDebounced = _.debounce(globalSearch, 100, false);
它只会在用户停止输入至少一秒钟后调用。
无法中断Array.filter
方法。根据您的需要,您可以这样处理:
let timerId = null
function handleChange() {
if(timerId) {
clearTimeout(timerId)
}
timerId = setTimeout(() => /* Array.filter(...) */, 1000)
}
说明
有一个变量,它将包含从 setTimeout
函数返回的 timerId
。每次更改模型时,都会调用 handleChange
函数(在本例中)。该函数检查包含timerId
的变量是否被设置并包含一个timerId
,当变量包含timerId
时将调用clearTimeout
函数来清除之前的超时之后 handleChange 创建一个新的超时并将 timerId
(从 setTimeout
函数返回)分配给变量。
setTimeout
的文档
clearTimeout
的文档
没有下划线,也没有超时(顺便说一句,这将触发整个 Angular 生命周期),您可以使用带有异步管道和去抖动的 Observable。
在您的全局搜索功能中:
return Observable.of(/* filter here and return the filtered array */).debounceTime(1000)
在你的列表中(我猜这一定是某个地方)
<list-item *ngFor="let x of myFilteredResults | async">...</list-item>
我已经用Subject
到debounceTime
完成了。
private subject = new Subject<string>()
ngOnInit() {
this.subject.debounceTime(300).subscribe(inputText => {
this.gloablFilterValue = inputText;
this.splitCustomFilter(); // filter method
});
}
现在,当我使用更改事件更改 this.gloablFilterValue
对象中的值时。它只是等待事件完成结束。