これは主に私の検索設定のショーケースであるため、ガイドラインや何かに違反していないことを願っています. 下部にいくつかの質問があります。約束します。
私は Sencha Touch 2 PhoneGap アプリを作成しました (これは現在iOS 用の AppStore で公開されており、Android はまもなく準備が整います)。このアプリの基本的な前提は、(やや巨大な) 検索可能なリスト (いくつかの追加フィルター付き) です。したがって、検索パフォーマンスは不可欠です。
私の検索コントローラーの概要: 例を見ていると、送信ボタンまたはキーアップ検索のいずれかを使用している人を見つけました。
私が見つけた例では、キーアップリスナーのみがアクティブ化されていました。簡単な修正です:
'searchfield[itemId=searchBox]' : {
clearicontap : 'onClearSearch',
keyup: 'onSearchKeyUp',
submit: 'onSubmit',
action: 'onSubmit',
paste: 'onSubmit',
blur: 'onSubmit'
}
では、なぜ keyup と submit が異なるのでしょうか? onSubmit 関数は検索関数を実行するだけです (詳細は後述)。onClearSearch は、ストアに設定されたフィルターをクリアしてから、非検索ベースのフィルターを再び追加します。
onSearchKeyUp 関数は興味深いところです。リストは巨大であるため、すべての文字を検索するとパフォーマンスが低下します。(特に古いデバイスでは) 検索中に検索フィールドが停止するため、ユーザーがキーボードで文字をタップし続けても何も表示されません。すべての検索機能が実際に実行されると、入力はユーザーが意図したものでさえない可能性があります。
ユーザーがいつ入力を終了したかを推測することで、これを修正しました。キーアップでタイマーをトリガーすることでこれを行いました。この場合は 650 ミリ秒です。この期間内に別のキーアップ イベントがトリガーされた場合、タイマーはキャンセルされ、コースを実行すると検索機能がトリガーされます。このタイマーは、もちろん高くも低くも設定できます。低いということは、入力中に検索しないように、ユーザーがより速く入力できることを意味します。高いということは、ユーザーが最後のキーアップ イベントから実際の検索を開始するまで、より長く待たなければならないことを意味します (遅延として認識されます)。
もちろん例外はありますが、キーアップ イベントがエンター キーからの場合は、すぐに検索されます。コード:
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)について-私は1つの方法、 store.filter('field', '', true); を見つけました。同じ方法で設定されたフィルターを実際にクリアします。ただし、同じ方法で検索フィルターをクリアできませんでした。