我希望我没有违反任何准则或任何内容,因为这主要是我的搜索设置的展示。底部有几个问题。我保证。
我制作了一个 Sencha Touch 2 PhoneGap 应用程序(现在在 iOS 的 AppStore中上线,Android 很快就会准备好)。该应用程序的基本前提是一个(有点大的)可搜索列表(带有几个额外的过滤器)。因此,搜索性能至关重要。
我的搜索控制器的概要:在查看示例时,我发现人们使用提交按钮或在 keyup 上搜索,因为后者对我最感兴趣,这就是我开始的地方。
在我找到的示例中,仅激活了 keyup 侦听器,这是一个快速修复:
'searchfield[itemId=searchBox]' : {
clearicontap : 'onClearSearch',
keyup: 'onSearchKeyUp',
submit: 'onSubmit',
action: 'onSubmit',
paste: 'onSubmit',
blur: 'onSubmit'
}
现在,您可能会问,为什么 keyup 和 submit 不同?好吧,onSubmit 函数只是运行搜索函数(稍后会详细介绍)。onClearSearch 只是清除在商店中设置的过滤器,然后将非基于搜索的过滤器添加回来。
onSearchKeyUp 函数是有趣的地方。由于列表很大,搜索每一个字母都意味着性能不佳。搜索字段在搜索时停止(尤其是在旧设备上),因此当用户继续在键盘上敲击字母时,什么都没有显示,同时排队 javascript 并且(在某些情况下)导致用户再次敲击字母,这样当所有搜索功能都实际完成时,输入甚至可能不是用户想要的。
我通过尝试推断用户何时完成输入来解决此问题。我通过让 keyup 触发一个计时器来做到这一点,在这种情况下为 650 毫秒,如果在此期间触发另一个 keyup 事件,则计时器被取消,如果它运行它的过程,它会触发搜索功能。这个计时器当然可以设置得更高或更低。较低意味着用户打字速度更快,因为它不会在打字时搜索。较高意味着用户将不得不从他们的最后一个 keyup 事件开始等待更长时间才能开始实际搜索(被认为是滞后)。
当然,也有一个例外,如果keyup事件来自回车键,则立即搜索。代码:
onSearchKeyUp: function(searchField,e) {
if (e.event.keyCode == 13){
window.clearTimeout(t);
window.timer_is_on=0;
searchFunction();
} else {
doTimer();
}
function timedCount()
{
t=setTimeout(function(){timedSearch();},650);
}
function timedSearch()
{
console.log('b4 search');
searchFunction();
window.timer_is_on=0;
}
function doTimer()
{
if (window.timer_is_on === 0)
{
window.timer_is_on=1;
timedCount();
} else {
window.clearTimeout(t);
window.timer_is_on=0;
console.log('cleared timeout');
doTimer();
}
}
}
onSubmit: function(searchField,e) {
if (window.timer_is_on === 0)
{
console.log('timer was not on when done was pressed');
} else {
console.log('timer was on when done was pressed');
window.clearTimeout(t);
window.timer_is_on=0;
searchFunction();
}
} else {
searchFunction();
},
所以对于搜索功能。我想我在这里可能还有一些改进的空间。首先,我注意到当我向下滚动列表并搜索时,我可能最终会低于实际列表内容,无法向上滚动。所以搜索功能做的第一件事就是滚动到顶部。
正如我在文章开头提到的,我有一些额外的过滤器。这些是工具栏按钮,基本上设置变量然后触发搜索功能。在搜索功能中,过滤是基于变量完成的。我结合了搜索和过滤功能,因为它们都需要清除过滤器并将它们重新添加。
您还会注意到加载掩码和延迟。延迟完全是经验性的,结果表明加载掩码需要 25 毫秒的延迟才能实际显示。
我的搜索功能代码:
function searchFunction() {
Ext.Viewport.setMasked({
xtype: 'loadmask',
message: 'Searching'
});
setTimeout(function() {
Ext.getCmp('lablist').getScrollable().getScroller().scrollTo(0,0);
var searchField = Ext.getCmp('searchBox');
queryString = searchField.getValue();
console.log('Please search by: ' + queryString);
var store = Ext.getStore('LabListStore');
store.clearFilter();
genderFilterFuncForSearch();
ageFilterFuncForSearch();
if(queryString){
var thisRegEx = new RegExp(queryString, "i");
store.filterBy(function(record) {
if (thisRegEx.test(record.get('Analysis'))||thisRegEx.test(record.get('Groupname'))) {
return true;
}
return false;
});
}},25);
}
function ageFilterFuncForSearch() {
if (ageFilter === 'A') {
Ext.getStore('LabListStore').filter('adult', '1');
} else if (ageFilter === 'C') {
Ext.getStore('LabListStore').filter('child', '1');
}
Ext.Viewport.setMasked(false);
}
function genderFilterFuncForSearch() {
if (genderFilter === 'M') {
Ext.getStore('LabListStore').filter('Male', '1');
} else if (genderFilter === 'F') {
Ext.getStore('LabListStore').filter('Female', '1');
}
}
这基本上是我的搜索设置。因为这是我的第一个 Sencha Touch 项目,所以它是一种基于反复试验的工作流程,但现在看起来相当不错。希望有人能分享一些建议(希望我有一些你们中的一些人没有想到的)。
其中很大一部分是从大量不同的 SO 帖子中收集的,谢谢!
我保证我会问一些问题:
- 您可以清除单个过滤器吗?
- 如果是这样,检查设置了哪些过滤器然后只清除那些调用 store.clearFilter 的过滤器会更好吗?
- 如您所见,我的搜索功能使用正则表达式,有没有办法在不将其转换为正则表达式对象的情况下实现相同类型的搜索,这对性能会更好吗?
PS。关于 1)- 我找到了一种方法, store.filter('field', '', true); 实际上会清除以相同方式设置的过滤器。我无法以同样的方式清除搜索过滤器。